2762

1 /*
2 此题,可用强连通分量算法缩图,然后拓扑排序判断是否为链。
3 */
4 // include file
5 #include <cstdio>
6 #include <cstdlib>
7 #include <cstring>
8 #include <cmath>
9 #include <cctype>
10 #include <ctime>
11
12 #include <iostream>
13 #include <sstream>
14 #include <fstream>
15 #include <iomanip>
16 #include <bitset>
17 #include <strstream>
18
19 #include <algorithm>
20 #include <string>
21 #include <vector>
22 #include <queue>
23 #include <set>
24 #include <list>
25 #include <functional>
26
27 using namespace std;
28
29 // typedef
30 typedef long long LL;
31 typedef unsigned long long ULL;
32
33 //
34 #define read freopen("in.txt","r",stdin)
35 #define write freopen("out.txt","w",stdout)
36 #define FORi(a,b) for(int i=(a);i<(b);i++)
37 #define FORj(a,b) for(int j=(a);j<(b);j++)
38 #define FORDi(a,b) for(int i=(a)-1;i>=0;i--)
39
40 #define FF(i,a) for(int i=0;i<(a);i+++)
41 #define FFD(i,a) for(int i=(a)-1;i>=0;i--)
42 #define Z(a) (a<<1)
43 #define Y(a) (a>>1)
44
45 const double eps = 1e-11;
46 const double Pi = acos(-1.0);
47
48 template<class T> inline T sqr(T a){return a*a;}
49 template<class T> inline T TMAX(T x,T y)
50 {
51 if(x>y) return x;
52 return y;
53 }
54 template<class T> inline T MMAX(T x,T y,T z)
55 {
56 return TMAX(TMAX(x,y),z);
57 }
58
59 // code begin
60 #define MAXN 1011
61
62 vector<int> G[MAXN];
63 vector<int> RG[MAXN];
64 vector<int> NG[MAXN];
65 queue<int> qI;
66 int in[MAXN];
67 int out[MAXN];
68
69 int scc;
70 int stk[MAXN],top;
71 int id[MAXN];
72 int used[MAXN];
73
74
75 int T,n,m;
76
77 void dfs(int i)
78 {
79 used[i] = 1;
80 int sz = G[i].size();
81 FORj(0,sz)
82 {
83 if( !used[ G[i][j] ] )
84 {
85 dfs(G[i][j]);
86 }
87 }
88 stk[top++] = i;
89 }
90
91 void rdfs(int i)
92 {
93 used[i] = 1;
94 id[i] = scc;
95 int sz = RG[i].size();
96 FORj(0,sz)
97 {
98 if( !used[ RG[i][j] ] )
99 {
100 rdfs( RG[i][j] );
101 }
102 }
103 }
104
105 int main()
106 {
107 read;
108 write;
109 scanf("%d",&T);
110
111 while(T--)
112 {
113 scanf("%d %d",&n,&m);
114
115 FORi(1,n+1)
116 {
117 G[i].clear();
118 RG[i].clear();
119 }
120
121 int a,b;
122 while(m--)
123 {
124 scanf("%d %d",&a,&b);
125 G[a].push_back(b);
126 RG[b].push_back(a);
127 }
128
129 top = 0;
130 memset(used,0,sizeof(used));
131 FORi(1,n+1)
132 {
133 if(!used[i])
134 {
135 dfs(i);
136 }
137 }
138
139 memset(used,0,sizeof(used));
140 memset(id,0,sizeof(id));
141 scc = 1;
142 FORDi(top,0)
143 {
144 if(!used[ stk[i] ])
145 {
146 rdfs( stk[i] );
147 scc ++;
148 }
149 }
150 FORi(1,scc)
151 {
152 NG[i].clear();
153 }
154
155 FORi(1,n+1)
156 {
157 FORj(0,G[i].size())
158 {
159 if( id[ i ]!=id[ G[i][j] ] )
160 {
161 NG[ id[i] ].push_back( id[ G[i][j] ] );
162 //tmp.push_back( id[G[i][j]] );
163 }
164 }
165 }
166 memset(in,0,sizeof(in));
167 FORi(1,scc)
168 {
169 vector<int> tmp = NG[i];
170 sort(tmp.begin(),tmp.end());
171 NG[i].clear();
172 if(tmp.size()>0)
173 {
174 NG[i].push_back(tmp[0]);
175 in[tmp[0]]++;
176 FORj(1,tmp.size())
177 {
178 if(tmp[j]!=tmp[j-1])
179 {
180 NG[i].push_back(tmp[j]);
181 in[tmp[j]]++;
182 }
183 }
184 }
185 }
186
187 // 对新图拓扑排序,不唯一就pass
188
189 memset(used,0,sizeof(used));
190 bool ok = false;
191 int cur;
192 FORi(1,scc)
193 {
194 if(in[i]==0)
195 {
196 ok = true;
197 used[i] = true;
198 cur = i;
199 break;
200 }
201 }
202
203 if(ok)
204 FORi(2,scc)
205 {
206 // 开始找第二个数
207 ok = false;
208 FORj(0,NG[cur].size())
209 {
210 in[ NG[cur][j] ]--;
211 if( in[ NG[cur][j] ]==0 && !used[NG[cur][j]])
212 {
213 ok = true;
214 used[ NG[cur][j] ]=1;
215 cur = NG[cur][j];
216 break;
217 }
218 }
219
220 if(!ok)
221 break;
222 }
223
224
225 ok?printf("Yes\n"):printf("No\n");
226 }
227 return 0;
228 }

posted @ 2011-02-27 19:53  AC2012  阅读(250)  评论(0编辑  收藏  举报