HDU

这是一个有向仙人掌的题目,要求判定给定的图是不是强连通图,而且每一条边只能出现在一个环中,这里有一个介绍有向仙人掌的文档:http://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
",(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 }
View Code
原文地址:https://www.cnblogs.com/rootial/p/3343611.html