码迷,mamicode.com
首页 > 其他好文 > 详细

受欢迎的牛 tarjan求scc模板

时间:2019-10-11 01:14:18      阅读:99      评论:0      收藏:0      [点我收藏+]

标签:ret   lin   ide   names   isp   tar   while   string   pen   

第一遍不太熟,第二遍飞快地打出来了


算是tarjan模板了吧,几天了也总算是有一点对tarjan求法过程的理解了。

if(!dfn[u])tarjan(u),low[x] = min(low[x],low[u]);//如果没有访问过u,则tarjan一下,如果u走出去搞到的low更小则用这个更新x的low

else if(ins[u])low[x] = min(low[x],dfn[u]);//如果u访问过但在栈里,那么u的low说不定已经被更新过了,如果此时令low[x]与low[u]取min,则回溯时作为祖先的u的low与dfn就不相等了欸在这道题里好像确实是等价的,可能在其他tarjan算法里不等价吧,那我还是不太知道为什么在这里与dfn[u]取min了。。。whatsapity..

技术图片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<vector>
 6 #include<queue>
 7 
 8 using namespace std; 
 9 
10 const int Maxn = 10010; 
11 
12 vector<int> g[Maxn],scc[Maxn];
13 int stack[Maxn],ins[Maxn],inscc[Maxn];
14 int dfn[Maxn],low[Maxn],oud[Maxn];
15 int n,m,cntv,cntscc,top;
16 
17 void tarjan(int x){
18     low[x] = dfn[x] = ++cntv;
19     ins[x] = 1,stack[++top] = x;
20     for(int i = 0;i < g[x].size();i++){
21         int u = g[x][i];
22         if(!dfn[u])tarjan(u),low[x] = min(low[x],low[u]);
23         else if(ins[u])low[x] = min(low[x],dfn[u]);
24     }
25     if(dfn[x] == low[x]){
26         int y = 0; cntscc++;
27         while(y != x){
28             y = stack[top--];
29             ins[y] = 0;
30             inscc[y] = cntscc;
31             scc[cntscc].push_back(y);
32         }
33     }
34 }
35 
36 int main(){
37     ios::sync_with_stdio(false);
38     cin >> n >> m;
39     for(int i = 1;i <= m;i++){
40         int x,y;
41         cin >> x >> y;
42         g[x].push_back(y);
43     }
44     for(int i = 1;i <= n;i++)if(!dfn[i])tarjan(i);
45     for(int i = 1;i <= cntscc;i++){
46         for(int j = 0;j < scc[i].size();j++){
47             int u = scc[i][j];
48             for(int k = 0;k < g[u].size();k++){
49                 int v = g[u][k];
50                 if(inscc[v] != i)oud[i]++;
51             }
52         }
53     }
54     int ans = 0;
55     for(int i = 1;i <= cntscc;i++)if(!oud[i]){
56         if(ans){printf("0");return 0;}
57         ans = scc[i].size();
58     }
59     cout << ans;
60 return 0;
61 }
View Code

 

受欢迎的牛 tarjan求scc模板

标签:ret   lin   ide   names   isp   tar   while   string   pen   

原文地址:https://www.cnblogs.com/Wangsheng5/p/11651417.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!