给出n个点,m条边,问是否任意两点u,v,是否满足u能够到达v,或者v能够到达u
自己写的时候以为缩一下点,然后再判断一下能不能拓扑排序就可以了
但是--wa---
后来看了这篇题解
http://edward-mj.com/archives/27
按紫书上讲的,如果图中存在有向环,则不存在拓扑排序,反之则存在
所以上面这幅图是满足拓扑排序的
但是因为u,v的入度都为0,u,v之间不能到达
所以缩点完之后的图应该满足是一条长链才行
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<stack> 6 #include<queue> 7 #include<vector> 8 using namespace std; 9 10 const int maxn = 20005; 11 int first[maxn]; 12 int low[maxn],pre[maxn],sc[maxn]; 13 int in[maxn],dout[maxn]; 14 int n,m; 15 int ecnt,scnt,dfs_clock; 16 stack<int> S; 17 18 vector<int> g[maxn]; 19 int c[maxn]; 20 int ans[maxn]; 21 22 struct Edge{ 23 int v,next; 24 }e[3*maxn]; 25 26 void init(){ 27 ecnt = 0; 28 memset(first,-1,sizeof(first)); 29 memset(in,0,sizeof(in)); 30 memset(dout,0,sizeof(dout)); 31 } 32 33 void addedges(int u,int v){ 34 e[ecnt].v = v; 35 e[ecnt].next = first[u]; 36 first[u] = ecnt++; 37 } 38 39 void dfs(int u){ 40 low[u] = pre[u] = ++dfs_clock; 41 S.push(u); 42 for(int i = first[u];~i;i = e[i].next){ 43 int v = e[i].v; 44 if(!pre[v]){ 45 dfs(v); 46 low[u] = min(low[u],low[v]); 47 } 48 else if(!sc[v]) low[u] = min(low[u],pre[v]); 49 } 50 if(pre[u] == low[u]){ 51 scnt++; 52 for(;;){ 53 int x = S.top();S.pop(); 54 sc[x] = scnt; 55 if(x == u) break; 56 } 57 } 58 } 59 60 void find_scc(){ 61 while(!S.empty()) S.pop(); 62 memset(low,0,sizeof(low));memset(pre,0,sizeof(pre)); 63 memset(sc,0,sizeof(sc)); 64 dfs_clock = scnt = 0; 65 for(int i = 1;i <= n;i++) if(!pre[i]) dfs(i); 66 } 67 68 bool topsort(int N) { 69 queue<int> s; 70 for (int i = 1; i <= N; i++) { 71 if (!in[i]) s.push(i); 72 if (s.size() == 2) return false; 73 } 74 while (!s.empty()) { 75 int u = s.front();s.pop(); 76 bool flag = false; 77 for (int i = 0; i < g[u].size(); i++) { 78 int v = g[u][i]; 79 in[v] -= 1; 80 if (!in[v]) { 81 if (flag) return false; 82 s.push(v); 83 flag = true; 84 } 85 } 86 } 87 return true; 88 } 89 90 91 int main(){ 92 int T; 93 scanf("%d",&T); 94 while(T--){ 95 scanf("%d %d",&n,&m); 96 init(); 97 for(int i = 1;i <= m;i++){ 98 int u,v; 99 scanf("%d %d",&u,&v); 100 addedges(u,v); 101 } 102 find_scc(); 103 if(scnt == 1) { 104 puts("Yes"); 105 continue; 106 } 107 for(int i = 1;i <= scnt;i++) g[i].clear(); 108 for(int u = 1;u <= n;u++){ 109 for(int i = first[u];~i;i = e[i].next){ 110 int v = e[i].v; 111 if(sc[u] != sc[v]) { 112 g[sc[u]].push_back(sc[v]); 113 in[sc[v]]++; 114 } 115 } 116 } 117 if(topsort(scnt)) puts("Yes"); 118 else puts("No"); 119 } 120 return 0; 121 }
时间: 2024-10-11 13:39:00