poj - 2553 (强连通分量)

题目来源: http://acm.pku.edu.cn/JudgeOnline/problem?id=2553

 

强连通分量,很简单的题目,照着模板水过了。

 

代码
1 #include <iostream>
2 #include <algorithm>
3  using namespace std;
4
5  const int M = 10005;
6  int cnt, scnt, nn;
7 int stack[M], ord[M], low[M], id[M], ans[M];
8 bool instack[M], map[M];
9 struct Node
10 {
11 int to;
12 Node *next;
13 };
14 Node *g[M];
15
16
17 bool cmp(int a, int b)
18 {
19 return a < b;
20 }
21
22 void Tarjan(int e) //Tarjan的DFS过程,不断更新 low 和 ord
23 {
24 low[e] = ++cnt;
25 ord[e] = cnt;
26 stack[++stack[0]] = e;
27 instack[e] = true;
28 Node *tmp = g[e];
29
30 while (tmp != NULL)
31 {
32 int t = tmp -> to;
33 if(!ord[t])
34 {
35 Tarjan(t);
36 if(low[t] < low[e])
37 low[e] = low[t];
38 }
39 else if(instack[t] && ord[t]<low[e])
40 low[e] = ord[t];
41 tmp = tmp -> next;
42 }
43
44 if(low[e] == ord[e]) //找到强连通分量的根
45 {
46 int t;
47 scnt ++;
48 do //找出强连通分支中的点
49 {
50 t = stack[stack[0]--];
51 id[t] = scnt;
52 instack[t] = false;
53 }while (t != e);
54 }
55
56 return ;
57 }
58
59 void find_components(int n) //Tarjan主过程,依次找出没有DFS的点
60 {
61 memset(instack, false, sizeof(instack));
62 memset(ord, 0, sizeof(ord));
63 cnt = scnt = 0;
64 stack[0] = 0; //记录栈里元素的个数
65 for(int i=1; i<=n; i++)
66 {
67 if(!ord[i])
68 Tarjan(i);
69 }
70
71 return ;
72 }
73
74 void insert(int u, int v)
75 {
76 Node *tmp = new Node;
77 tmp -> to = v;
78 tmp -> next = g[u];
79 g[u] = tmp;
80 }
81
82 int main()
83 {
84 int n, m;
85 while (scanf("%d",&n)!=EOF && n)
86 {
87 scanf("%d",&m);
88 memset(g, NULL, sizeof(g));
89 for(int i=0; i<m; i++) //建图
90 {
91 int u, v ;
92 scanf("%d%d",&u,&v);
93 insert(u, v);
94 }
95
96 find_components(n);
97 nn = scnt;
98 memset(map, false, sizeof(map));
99
100 for(int i=1; i<=n; i++)
101 {
102 Node *tmp;
103 tmp = g[i];
104 while (tmp != NULL)
105 {
106 int e = tmp -> to;
107 if(id[e]!=id[i] && !map[id[i]])
108 map[id[i]] = true;
109 tmp = tmp -> next;
110 }
111 }
112
113 int k = 0;
114 for(int i=1; i<=n; i++)
115 {
116 int pos = id[i];
117 if(!map[pos])
118 {
119 ans[k++] = i;
120 }
121 }
122
123 if(k > 0)
124 {
125 sort(ans, ans+k, cmp);
126 printf("%d",ans[0]);
127 for(int i=1; i<k; i++)
128 printf(" %d",ans[i]);
129 printf("\n");
130 }
131 else
132 printf("\n\n");
133 }
134 return 0;
135 }
136
137
138

 

posted @ 2010-05-21 19:42  六少  阅读(680)  评论(0编辑  收藏  举报