HDU 3639 SCC Hawk-and-Chicken

求SCC缩点,统计出每个SCC中的点的个数。

然后统计能到达u的最多的点的个数,可以反向建图,再dfs一遍统计出来。

最后说一下,有必要开一个标记数组,因为测试数据中有重边,结果无限WA。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <vector>
  6 #include <stack>
  7 using namespace std;
  8 
  9 const int maxn = 5000 + 10;
 10 int n, m;
 11 vector<int> G[maxn];
 12 
 13 stack<int> S;
 14 int pre[maxn], lowlink[maxn], sccno[maxn], sz[maxn], dfs_clock, scc_cnt;
 15 
 16 void dfs(int u)
 17 {
 18     pre[u] = lowlink[u] = ++dfs_clock;
 19     S.push(u);
 20 
 21     for(int i = 0; i < G[u].size(); i++)
 22     {
 23         int v = G[u][i];
 24         if(!pre[v])
 25         {
 26             dfs(v);
 27             lowlink[u] = min(lowlink[u], lowlink[v]);
 28         }
 29         else if(!sccno[v]) lowlink[u] = min(lowlink[u], pre[v]);
 30     }
 31 
 32     if(pre[u] == lowlink[u])
 33     {
 34         scc_cnt++;
 35         for(;;)
 36         {
 37             int x = S.top(); S.pop();
 38             sccno[x] = scc_cnt;
 39             sz[scc_cnt]++;
 40             if(x == u) break;
 41         }
 42     }
 43 }
 44 
 45 void find_scc()
 46 {
 47     dfs_clock = scc_cnt = 0;
 48     memset(pre, 0, sizeof(pre));
 49     memset(sccno, 0, sizeof(sccno));
 50     memset(sz, 0, sizeof(sz));
 51     for(int i = 0; i < n; i++) if(!pre[i]) dfs(i);
 52 }
 53 
 54 int support[maxn];
 55 int indeg[maxn];
 56 bool vis[maxn];
 57 vector<int> G2[maxn];
 58 
 59 int dfs2(int u)
 60 {
 61     int ans = sz[u];
 62     vis[u] = true;
 63     for(int i = 0; i < G2[u].size(); i++)
 64     {
 65         int v = G2[u][i];
 66         if(vis[v]) continue;
 67         ans += dfs2(v);
 68     }
 69     return ans;
 70 }
 71 
 72 int main()
 73 {
 74     int T; scanf("%d", &T);
 75     for(int kase = 1; kase <= T; kase++)
 76     {
 77         scanf("%d%d", &n, &m);
 78         for(int i = 0; i < n; i++) G[i].clear();
 79         while(m--)
 80         {
 81             int u, v; scanf("%d%d", &u, &v);
 82             G[u].push_back(v);
 83         }
 84 
 85         find_scc();
 86 
 87         memset(indeg, 0, sizeof(indeg));
 88         for(int i = 1; i <= scc_cnt; i++) G2[i].clear();
 89         for(int i = 0; i < n; i++)
 90             for(int j = 0; j < G[i].size(); j++)
 91             {
 92                 int u = sccno[i], v = sccno[G[i][j]];
 93                 if(u == v) continue;
 94                 indeg[u]++;
 95                 G2[v].push_back(u);
 96             }
 97 
 98         int ans = 0;
 99         for(int i = 1; i <= scc_cnt; i++) if(!indeg[i])
100         {
101             memset(vis, false, sizeof(vis));
102             support[i] = dfs2(i);
103             ans = max(ans, support[i]);
104         }
105 
106         printf("Case %d: %d\n", kase, ans - 1);
107         bool flag = false;
108         for(int i = 0; i < n; i++)
109         {
110             int u = sccno[i];
111             if(!indeg[u] && support[u] == ans)
112             {
113                 if(flag) printf(" ");
114                 printf("%d", i);
115                 flag = true;
116             }
117         }
118         puts("");
119     }
120 
121     return 0;
122 }
代码君

 

posted @ 2015-08-10 23:11  AOQNRMGYXLMV  阅读(247)  评论(0编辑  收藏  举报