1236

1 /*
2 用到强连通分量算法,缩图。构建新图,查看出度为0的点和入度为0的点
3 问题1的答案很明显,入度为0的点是必须先发布给它的
4 问题2的答案,猜测是这样的。要想全连通,即任何一个学校到另外一所
5 学校都有路径,那么所有的节点都必须有入和出,不能出现入度和出度为0
6 的情况,所以最好的答案就是入度和出度的最大值了。
7 */
8 // include file
9 #include <cstdio>
10 #include <cstdlib>
11 #include <cstring>
12 #include <cmath>
13 #include <cctype>
14 #include <ctime>
15
16 #include <iostream>
17 #include <sstream>
18 #include <fstream>
19 #include <iomanip>
20 #include <bitset>
21 #include <strstream>
22
23 #include <algorithm>
24 #include <string>
25 #include <vector>
26 #include <queue>
27 #include <set>
28 #include <list>
29 #include <functional>
30
31 using namespace std;
32
33 // typedef
34 typedef long long LL;
35 typedef unsigned long long ULL;
36
37 //
38 #define read freopen("in.txt","r",stdin)
39 #define write freopen("out.txt","w",stdout)
40 #define FORi(a,b) for(int i=(a);i<(b);i++)
41 #define FORj(a,b) for(int j=(a);j<(b);j++)
42 #define FORDi(a,b) for(int i=(a)-1;i>=0;i--)
43
44 #define FF(i,a) for(int i=0;i<(a);i+++)
45 #define FFD(i,a) for(int i=(a)-1;i>=0;i--)
46 #define Z(a) (a<<1)
47 #define Y(a) (a>>1)
48
49 const double eps = 1e-11;
50 const double Pi = acos(-1.0);
51
52 template<class T> inline T sqr(T a){return a*a;}
53 template<class T> inline T TMAX(T x,T y)
54 {
55 if(x>y) return x;
56 return y;
57 }
58 template<class T> inline T MMAX(T x,T y,T z)
59 {
60 return TMAX(TMAX(x,y),z);
61 }
62
63 // code begin
64 #define MAXN 101
65
66 vector<int> G[MAXN];
67 vector<int> RG[MAXN];
68 bool NG[MAXN][MAXN];
69 int in[MAXN];
70 int out[MAXN];
71
72 int scc;
73 int stk[MAXN],top;
74 int id[MAXN];
75 int used[MAXN];
76
77 vector<int> ans;
78
79 int n,m;
80
81 void dfs(int i)
82 {
83 used[i] = 1;
84 int sz = G[i].size();
85 FORj(0,sz)
86 {
87 if( !used[ G[i][j] ] )
88 {
89 dfs(G[i][j]);
90 }
91 }
92 stk[top++] = i;
93 }
94
95 void rdfs(int i)
96 {
97 used[i] = 1;
98 id[i] = scc;
99 int sz = RG[i].size();
100 FORj(0,sz)
101 {
102 if( !used[ RG[i][j] ] )
103 {
104 rdfs( RG[i][j] );
105 }
106 }
107 }
108
109 int main()
110 {
111 read;
112 write;
113 while(scanf("%d",&n)==1)
114 {
115
116 FORi(1,n+1)
117 {
118 G[i].clear();
119 RG[i].clear();
120 }
121
122 int a;
123 FORi(1,n+1)
124 {
125 while(true)
126 {
127 scanf("%d",&a);
128 if(a==0) break;
129 G[i].push_back(a);
130 RG[a].push_back(i);
131 }
132 }
133
134 top = 0;
135 memset(used,0,sizeof(used));
136 FORi(1,n+1)
137 {
138 if(!used[i])
139 {
140 dfs(i);
141 }
142 }
143
144 memset(used,0,sizeof(used));
145 memset(id,0,sizeof(id));
146 scc = 1;
147 FORDi(top,0)
148 {
149 if(!used[ stk[i] ])
150 {
151 rdfs( stk[i] );
152 scc ++;
153 }
154 }
155
156 memset(NG,0,sizeof(NG));
157 FORi(1,n+1)
158 {
159 FORj(0,G[i].size())
160 {
161 if( id[ i ]!=id[ G[i][j] ] )
162 {
163 NG[ id[i] ][ id[ G[i][j] ] ] = 1;
164 }
165 }
166 }
167
168 memset(in,0,sizeof(in));
169 memset(out,0,sizeof(out));
170 FORi(1,scc)
171 {
172 FORj(1,scc)
173 {
174 out[i]+=NG[i][j];
175 in[j]+=NG[i][j];
176 }
177 }
178
179 int ansin=0,ansout=0;
180 FORi(1,scc)
181 {
182 if(in[i]==0) ansin++;
183 if(out[i]==0) ansout++;
184 }
185
186 if(scc>2) printf("%d\n%d\n",ansin,TMAX(ansin,ansout));
187 else printf("1\n0\n");
188 }
189 return 0;
190 }
posted @ 2011-02-27 17:08  AC2012  阅读(810)  评论(0编辑  收藏  举报