poj 2762(强连通+判断链)

题目链接:http://poj.org/problem?id=2762

思路:首先当然是要缩点建新图,由于题目要求是从u->v或从v->u连通,显然是要求单连通了,也就是要求一条长链了,最后只需判断链长是否等于新图顶点个数即可,至于如何求一条链长,直接dfs即可,注意点就是dfs是要从入度为0的顶点开始。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stack>
 6 #include<vector>
 7 using namespace std;
 8 #define MAXN 1010
 9 
10 int low[MAXN],dfn[MAXN],color[MAXN];
11 bool mark[MAXN];
12 int to[MAXN];
13 int n,m,cnt,_count,ans;
14 
15 vector<vector<int> >map;
16 vector<vector<int> >Graph;
17 stack<int>S;
18 
19 void Tarjan(int u)
20 {
21     low[u]=dfn[u]=++cnt;
22     mark[u]=true;
23     S.push(u);
24     for(int i=0;i<map[u].size();i++){
25         int v=map[u][i];
26         if(dfn[v]==0){
27             Tarjan(v);
28             low[u]=min(low[u],low[v]);
29         }else if(mark[v]){
30             low[u]=min(low[u],dfn[v]);
31         }
32     }
33     if(low[u]==dfn[u]){
34         int v;
35         _count++;
36         do{
37             v=S.top();
38             S.pop();
39             mark[v]=false;
40             color[v]=_count;
41         }while(u!=v);
42     }
43 }
44 
45 void dfs(int u)
46 {
47     mark[u]=true;
48     for(int i=0;i<Graph[u].size();i++){
49         int v=Graph[u][i];
50         if(!mark[v]){ 
51             ans++;
52             dfs(v); 
53             return ;
54         }
55     }
56 }
57     
58 int main()
59 {
60     int u,v,_case;
61     scanf("%d",&_case);
62     while(_case--){
63         scanf("%d%d",&n,&m);
64         map.clear();Graph.clear();
65         map.resize(n+2);Graph.resize(n+2);
66         cnt=_count=0;
67         for(int i=1;i<=m;i++){
68             scanf("%d%d",&u,&v);
69             map[u].push_back(v);
70         }
71         memset(dfn,0,(n+2)*sizeof(int));
72         memset(to,0,(n+2)*sizeof(int));
73         memset(mark,false,(n+2)*sizeof(bool));
74         for(int i=1;i<=n;i++){
75             if(dfn[i]==0)Tarjan(i);
76         }
77         for(int i=1;i<=n;i++){
78             for(int j=0;j<map[i].size();j++){
79                 if(color[i]!=color[map[i][j]]){
80                     Graph[color[i]].push_back(color[map[i][j]]);
81                     to[color[map[i][j]]]++;
82                 }
83             }
84         }
85         ans=1;
86         for(int i=1;i<=_count;i++){
87             if(to[i]==0){ dfs(i);break; }
88         }
89         (ans==_count)?puts("Yes"):puts("No");
90     }
91     return 0;
92 }
View Code

 

posted @ 2013-07-22 17:31  ihge2k  阅读(416)  评论(1编辑  收藏  举报