POJ2762 Going from u to v or from v to u?(判定单连通图:强连通分量+缩点+拓扑排序)
这道题要判断一张有向图是否是单连通图,即图中是否任意两点u和v都存在u到v或v到u的路径。
方法是,找出图中所有强连通分量,强连通分量上的点肯定也是满足单连通性的,然后对强连通分量进行缩点,缩点后就变成DAG。
现在问题就变成,如何判断DAG是否是单连通图——用拓扑排序——如果拓扑排序过程中出现1个以上入度为0的点那就不是单连通图,因为有2个入度0的点,那这两个点肯定都无法到达对方。
另外,注意题目没说给的图是连通的!。。
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<algorithm> 5 using namespace std; 6 #define MAXN 1111 7 #define MAXM 6666 8 struct Edge{ 9 int u,v,next; 10 }edge[MAXM]; 11 int NE,head[MAXN]; 12 void addEdge(int u,int v){ 13 edge[NE].u=u; edge[NE].v=v; edge[NE].next=head[u]; 14 head[u]=NE++; 15 } 16 17 int belong[MAXN],bn,stack[MAXN],top; 18 bool instack[MAXN]; 19 int dn,dfn[MAXN],low[MAXN]; 20 void dfs(int u){ 21 dfn[u]=low[u]=++dn; 22 stack[++top]=u; instack[u]=1; 23 for(int i=head[u]; i!=-1; i=edge[i].next){ 24 int v=edge[i].v; 25 if(dfn[v]==0){ 26 dfs(v); 27 low[u]=min(low[u],low[v]); 28 }else if(instack[v]){ 29 low[u]=min(low[u],dfn[v]); 30 } 31 } 32 if(dfn[u]==low[u]){ 33 int v; ++bn; 34 do{ 35 v=stack[top--]; 36 belong[v]=bn; 37 instack[v]=0; 38 }while(u!=v); 39 } 40 } 41 42 int deg[MAXN]; 43 bool toposort(){ 44 queue<int> que; 45 for(int i=1; i<=bn; ++i){ 46 if(deg[i]==0) que.push(i); 47 } 48 if(que.size()>1) return 0; 49 while(!que.empty()){ 50 int u=que.front(); que.pop(); 51 for(int i=head[u]; i!=-1; i=edge[i].next){ 52 int v=edge[i].v; 53 if(--deg[v]==0) que.push(v); 54 } 55 if(que.size()>1) return 0; 56 } 57 return 1; 58 } 59 int main(){ 60 int t,n,m,a,b; 61 scanf("%d",&t); 62 while(t--){ 63 NE=0; 64 memset(head,-1,sizeof(head)); 65 scanf("%d%d",&n,&m); 66 while(m--){ 67 scanf("%d%d",&a,&b); 68 addEdge(a,b); 69 } 70 71 top=bn=dn=0; 72 memset(instack,0,sizeof(instack)); 73 memset(dfn,0,sizeof(dfn)); 74 for(int i=1; i<=n; ++i){ 75 if(dfn[i]==0) dfs(i); 76 } 77 78 int tmp=NE; NE=0; 79 memset(head,-1,sizeof(head)); 80 memset(deg,0,sizeof(deg)); 81 for(int i=0; i<tmp; ++i){ 82 int u=belong[edge[i].u],v=belong[edge[i].v]; 83 if(u==v) continue; 84 addEdge(u,v); 85 ++deg[v]; 86 } 87 if(toposort()) puts("Yes"); 88 else puts("No"); 89 } 90 return 0; 91 }