HDU - 3594 Cactus
这是一个有向仙人掌的题目,要求判定给定的图是不是强连通图,而且每一条边只能出现在一个环中,这里有一个介绍有向仙人掌的文档:https://files.cnblogs.com/ambition/cactus_solution.pdf。
有向仙人掌的判定:
1.dfs树中不存在横叉边;
2.dfs树中不存在lowlink[v]>pre[u],也就是不存在桥,lowlink[v]表示从v及其子节点出发能回到的pre值最小的祖先的pre值;
3.从节点u出发的点v,满足pre[v] < pre[u](当(u,v)是反向边时),和lowlink[v] < pre[u]的个数< 2.
更详细的解答见这里:http://blog.csdn.net/frog1902/article/details/10051323#comments
我又按照这思路简单写了一遍,加深理解>.<
代码:
1 #include <iostream> 2 #include <sstream> 3 #include <cstdio> 4 #include <climits> 5 #include <cstring> 6 #include <cstdlib> 7 #include <string> 8 #include <stack> 9 #include <map> 10 #include <cmath> 11 #include <vector> 12 #include <queue> 13 #include <algorithm> 14 #define esp 1e-6 15 #define pi acos(-1.0) 16 #define pb push_back 17 #define mp(a, b) make_pair((a), (b)) 18 #define in freopen("in.txt", "r", stdin); 19 #define out freopen("out.txt", "w", stdout); 20 #define print(a) printf("%d\n",(a)); 21 #define bug puts("********))))))"); 22 #define stop system("pause"); 23 #define Rep(i, c) for(__typeof(c.end()) i = c.begin(); i != c.end(); i++) 24 #define inf 0x0f0f0f0f 25 26 using namespace std; 27 typedef long long LL; 28 typedef vector<int> VI; 29 typedef pair<int, int> pii; 30 typedef vector<pii,int> VII; 31 typedef vector<int>:: iterator IT; 32 33 const int maxn = 20000 + 10; 34 int pre[maxn], lowlink[maxn], cost[maxn], vis[maxn], dfs_clock; 35 VI g[maxn]; 36 int flag; 37 void dfs(int u) 38 { 39 lowlink[u] = pre[u] = ++dfs_clock; 40 vis[u] = 1; 41 for(int i = 0; i < g[u].size(); i++) 42 { 43 if(!flag) return; 44 int v = g[u][i]; 45 if(!vis[v] && pre[v]) 46 { 47 flag = 0; 48 return; 49 } 50 if(!pre[v]) 51 { 52 dfs(v); 53 lowlink[u] = min(lowlink[u], lowlink[v]); 54 if(lowlink[v] < pre[u]) cost[u]++; 55 if(lowlink[v] > pre[u]) 56 { 57 flag = 0; 58 return; 59 } 60 } 61 else if(pre[v] < pre[u]) 62 { 63 lowlink[u] = min(lowlink[u], pre[v]); 64 cost[u]++; 65 } 66 if(cost[u] > 1) 67 { 68 flag = 0; 69 return; 70 } 71 } 72 vis[u] = 0; 73 } 74 void solve(int n) 75 { 76 memset(pre, 0, sizeof(pre)); 77 memset(vis, 0, sizeof(vis)); 78 memset(lowlink, 0, sizeof(lowlink)); 79 memset(cost, 0, sizeof(cost)); 80 81 dfs_clock = 0; 82 for(int i = 0; i < n ; i++) 83 if(!pre[i]) 84 { 85 dfs(i); 86 if(!flag) break; 87 } 88 } 89 int main(void) 90 { 91 int T; 92 for(int t = scanf("%d", &T); t <= T; t++) 93 { 94 flag = 1; 95 for(int i = 0; i < maxn; i++) 96 g[i].clear(); 97 int n; 98 scanf("%d", &n); 99 int u, v; 100 while(scanf("%d%d", &u, &v), u||v) 101 { 102 g[u].pb(v); 103 } 104 solve(n); 105 if(flag) 106 puts("YES"); 107 else puts("NO"); 108 } 109 return 0; 110 }