POJ 2762 Going from u to v or from v to u?- Tarjan

Description

判断一个有向图是否对于任意两点 $x$,  $y$ 都有一条路径使$x - >y$或 $y - >x$

Solution

对于一个强联通分量内的点 都是可以互相到达的。

接下来我们考虑缩点后的DAG是否任意两点都有路径能使一点到达另一点。

 

然后我就不会了~~

我们进行一遍拓扑排序, 如果过程中有超过一个点的入度为 $0$ ,那么就不符合条件(仔细想想好像还是对的

Code

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<queue>
  5 #define rd read()
  6 #define R register
  7 using namespace std;
  8 
  9 const int N = 1e5;
 10 
 11 int head[N], tot;
 12 int Head[N], Tot;
 13 int dfn[N], low[N], st[N] ,tp, vis[N], cnt;
 14 int col_num, col[N], ru[N];
 15 int n, m, T;
 16 
 17 queue<int> q;
 18 
 19 struct edge {
 20     int nxt, to, fr;
 21 }e[N << 2], E[N << 2];
 22 
 23 int read() {
 24     int X = 0, p = 1; char c = getchar();
 25     for(; c > '9' || c < '0'; c = getchar()) if(c == '-') p = -1;
 26     for(; c >= '0' && c <= '9'; c = getchar()) X = X * 10 + c - '0';
 27     return X * p;
 28 }
 29 
 30 void add(int u, int v) {
 31     e[++tot].to = v;
 32     e[tot].nxt = head[u];
 33     e[tot].fr = u;
 34     head[u] = tot;
 35 }
 36 
 37 void Add(int u, int v) {
 38     E[++Tot].to = v;
 39     E[Tot].nxt = Head[u];
 40     E[Tot].fr = u;
 41     Head[u] = Tot;
 42 }
 43 
 44 bool topsort() {
 45     int num = 0;
 46     for(int i = 1; i <= tot; ++i) {
 47         int u = col[e[i].fr], v = col[e[i].to];
 48         if(u == v) continue;
 49         ru[v]++;
 50         Add(u, v);
 51     }
 52     for(int i = 1; i <= col_num; ++i) 
 53         if(ru[i] == 0) num++, q.push(i);
 54     if(num > 1) 
 55         return 0;
 56     for(int u; !q.empty();) {
 57         if(num > 1) return 0;
 58         u = q.front(); q.pop();
 59         num--;
 60         for(int i = Head[u]; i; i = E[i].nxt) {
 61             int nt = E[i].to;
 62             ru[nt]--;
 63             if(!ru[nt])
 64                 num++, q.push(nt);
 65         }
 66     }
 67     return 1;
 68 }
 69 
 70 void tarjan(int u) {
 71     dfn[u] = low[u] = ++cnt;
 72     st[++tp] = u;
 73     vis[u] = 1;
 74     for(R int i = head[u]; i; i = e[i].nxt) {
 75         int nt = e[i].to;
 76         if(!dfn[nt]) {
 77             tarjan(nt);
 78             low[u] = min(low[u], low[nt]);
 79         }
 80         else if(vis[nt]) low[u] = min(low[u], dfn[nt]);
 81     }
 82     if(low[u] == dfn[u]) {
 83         ++col_num;
 84         for(; tp; ) {
 85             int z = st[tp--];
 86             vis[z] = 0;
 87             col[z] = col_num;
 88             if(z == u) break;
 89         }
 90     }
 91 }
 92 
 93 void init() {
 94     Tot = tp = tot = cnt = col_num = 0;
 95     memset(vis, 0 ,sizeof(vis));
 96     memset(dfn, 0, sizeof(dfn));
 97     memset(col, 0, sizeof(col));
 98     memset(head, 0, sizeof(head));
 99     memset(low, 0, sizeof(low));
100     memset(st, 0, sizeof(tp));
101     memset(Head, 0, sizeof(Head));
102     memset(ru, 0, sizeof(ru));
103     while(!q.empty()) q.pop();
104 }
105 
106 int main()
107 {
108     T = rd;
109     for(; T; T--) {
110         init();
111         n = rd; m = rd;
112         for(int i = 1;  i <= m; ++i) {
113             int u = rd, v = rd;
114             add(u, v);
115         }
116         for(int i = 1; i <= n; ++i) 
117             if(!dfn[i]) tarjan(i);
118         if(topsort()) puts("Yes");
119         else puts("No");
120     }
121 }
View Code
原文地址:https://www.cnblogs.com/cychester/p/9636909.html