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 }

 

posted @ 2016-01-24 18:25  WABoss  阅读(590)  评论(0编辑  收藏  举报