洛谷P2863 [USACO06JAN]牛的舞会The Cow Prom

稍微学习一下强连通分量。

https://www.cnblogs.com/stxy-ferryman/p/7779347.html

我觉得他讲得很好。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <vector>
 6 #include <stack>
 7 using namespace std;
 8 const int MAXN = 1e5 + 20;
 9 
10 int N, M;
11 
12 namespace SCC
13 {
14     vector<int> g[MAXN];
15     stack<int> sta;
16     bool ins[MAXN]; 
17     int idx[MAXN], dfn[MAXN], low[MAXN];
18     vector<int> scc[MAXN]; int cnt = 0;
19 
20     void tarjan(int cur)
21     {
22         static int num = 0;
23         dfn[cur] = low[cur] = ++num;
24         sta.push(cur), ins[cur] = true;
25         for(int i = 0; i < (int) g[cur].size(); i++){
26             int v = g[cur][i];
27             if(!dfn[v]) {
28                 tarjan(v);
29                 low[cur] = min(low[cur], low[v]);
30             }
31             else if(ins[v]) low[cur] = min(low[cur], dfn[v]);
32         }
33         if(dfn[cur] == low[cur]){
34             ++cnt; int tmp;
35             do{
36                 tmp = sta.top(); sta.pop(); ins[tmp] = false;
37                 idx[tmp] = cnt, scc[cnt].push_back(tmp);
38             }while(tmp != cur);
39         }
40     }
41 }
42 
43 int main()
44 {
45     cin>>N>>M;
46     for(int i = 1, u, v; i <= M; i++){
47         scanf("%d%d", &u, &v);
48         SCC::g[u].push_back(v);
49     }
50 
51     for(int i = 1; i <= N; i++)
52         if(!SCC::dfn[i]) SCC::tarjan(i);
53     int ans = 0;
54     for(int i = 1; i <= SCC::cnt; i++)
55         if(SCC::scc[i].size() > 1) ++ans;
56     cout<<ans<<endl;
57     return 0;
58 }

 

posted @ 2018-07-07 21:45  俺是小程  阅读(201)  评论(0编辑  收藏  举报