本文主要是介绍T103440 【模板】缩点,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目地址
易错点:
- 出栈时应将inStck[y]置空.
#include<cstdio>
#include<iostream>
using namespace std;
const int MAXN=1e5,MAXM=1e6;
struct Edge{int from,to,nxt;
}e[MAXM];
int head[MAXN],edgeCnt=1;
void addEdge(int u,int v){e[++edgeCnt].from=u;e[edgeCnt].to=v;e[edgeCnt].nxt=head[u];head[u]=edgeCnt;
}
int dfn[MAXN],low[MAXN],dfnCnt=0;
int stck[MAXN],top=0;
bool inStck[MAXN];
int inScc[MAXN],sccCnt=0;
int pointVal[MAXN];
int sumVal[MAXN];
void tarjan(int x){dfn[x]=low[x]=++dfnCnt;stck[++top]=x;inStck[x]=1;for(int i=head[x];i;i=e[i].nxt){int nowV=e[i].to;if(!dfn[nowV]){tarjan(nowV);low[x]=min(low[x],low[nowV]);}else if(inStck[nowV]){low[x]=min(low[x],dfn[nowV]);}}if(low[x]==dfn[x]){int y;sccCnt++;do{y=stck[top--];inScc[y]=sccCnt;inStck[y]=0;sumVal[sccCnt]+=pointVal[y];}while(x!=y);}
}
bool vis[MAXN];
int main(){int n,m;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%d",&pointVal[i]);for(int i=1;i<=m;i++){int u,v;scanf("%d%d",&u,&v);addEdge(u,v);}for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);for(int i=1;i<=n;i++){if(!vis[inScc[i]]){vis[inScc[i]]=1;printf("%d\n",sumVal[inScc[i]]);}}return 0;
}
这篇关于T103440 【模板】缩点的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!