# bzoj 1051: [HAOI2006]受欢迎的牛

tarjan强连通分量求缩点重构图，出度为0的点若只有一个则输出其代表强连通分量的大小，否则无解。

  1 /*
2 ID:WULALA
3 PROB:bzoj1051
4 LANG:C++
5 */
6 #include <cstdio>
7 #include <cstring>
8 #include <algorithm>
9 #include <cmath>
10 #include <iostream>
11 #include <fstream>
12 #include <ctime>
13 #define N 10008
14 #define M 50008
15 #define mod
16 #define mid(l,r) ((l+r) >> 1)
17 #define INF 0x7ffffff
18 using namespace std;
19
21 bool vis[N],inq[N],flag;
22
23 struct WULALA
24 {
25     int node,next;
26 }e[M],d[M];
27
28 void init()
29 {
30     scanf("%d%d",&n,&m);
31     for (int i = 1;i <= m;i++)
32     {
33         int x,y;
34         scanf("%d%d",&x,&y);
35         e[i].node = y;
38     }
39 }
40
41 void dfs(int a)
42 {
43     vis[a] = true;
44     low[a] = dfn[a] = ++cnt;
45     inq[a] = true; que[++r] = a;
47     while(c)
48     {
49         if (!vis[e[c].node])
50         {
51             dfs(e[c].node);
52             low[a] = min(low[a],low[e[c].node]);
53         }
54         else if (inq[e[c].node]) low[a] = min(low[a],dfn[e[c].node]);//要判是否在队列里！！
55         c = e[c].next;
56     }
57     if (low[a] == dfn[a])
58     {
59         belong[a] = ++scc;
60         hav[scc] = 1;
61         while (que[r] != a)
62         {
63             belong[que[r]] = scc;
64             inq[que[r]] = false;
65             ++hav[scc];
66             --r;
67         }
68         inq[que[r]] = false;//!!!
69         --r;//!!!
70     }
71 }
72
73 void rebuild()
74 {
75     cnt = 0;
76     for (int i = 1;i <= n;i++)
77     {
79         while(c)
80         {
81             if (belong[i] != belong[e[c].node])
82             {
83                 d[++cnt].node = belong[e[c].node];
84                 d[cnt].next = h[belong[i]];
85                 h[belong[i]] = cnt;
86             }
87             c = e[c].next;
88         }
89     }
90 }
91
92 void tarjan()
93 {
94
95     for (int i = 1;i <= n;i++)
96         if (!vis[i]) dfs(i);
97     rebuild();
98 }
99
100 void work()
101 {
102     for (int i = 1;i <= scc;i++)
103         if (!h[i])
104         {
105             if (ans)
106             {
107                 ans = 0;
108                 return;
109             }
110             else ans = hav[i];
111         }
112 }
113
114 int main()
115 {
116     init();
117     tarjan();
118     work();
119     printf("%d\n",ans);
120     return 0;
121 }
View Code

posted @ 2014-01-06 18:50  乌拉拉979  阅读(127)  评论(0编辑  收藏