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

 

你可能感兴趣的:(poj)