Tarjan 求桥,割,强连通

最近遇到了这种模板题,记录一下

tarjan求桥,求割

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define MOD 998244353
 4 #define INF 0x3f3f3f3f3f3f3f3f
 5 #define LL long long
 6 #define MX 1005
 7 
 8 int n, m, Ddex;
 9 vector<int> G[MX];
10 int fat[MX];
11 int low[MX],dfn[MX];
12 bool is_cut[MX];
13 
14 void Init()
15 {
16     Ddex=0;
17     for (int i=1;i<=n;i++) G[i].clear();
18     memset(dfn,-1,sizeof(dfn));
19     memset(fat,-1,sizeof(fat));
20     memset(is_cut,0,sizeof(is_cut));
21 }
22 
23 void Tarjan(int i,int pre)
24 {
25     fat[i]=pre;
26     dfn[i]=low[i]=++Ddex;
27     for(int j=0;j<G[i].size();++j)
28     {
29         int k=G[i][j];
30         if(dfn[k]==-1)
31         {
32             Tarjan(k,i);
33             low[i]=min(low[i],low[k]);
34         }
35         else if(k!=pre) //假如k是i的父亲的话,那么这就是无向边中的重边,有重边那么一定不是桥*/
36             low[i]=min(low[i],dfn[k]);
37     }
38 }
39 void calc()
40 {
41     int rootson=0;
42     Tarjan(1,-1);
43     for(int i=2;i<=n;++i)
44     {
45         int v=fat[i];
46         if(v==1)
47             rootson++; //统计根节点子树的个数,根节点的子树个数>=2,就是割点
48         else{
49             if(low[i]>=dfn[v]) //割点的条件
50                 is_cut[v]=true;
51         }
52     }
53     if(rootson>1)
54         is_cut[1]=true;
55     for(int i=1;i<=n;++i)
56         if(is_cut[i])
57             printf("%d\n",i);
58 
59     for(int i=1;i<=n;++i)
60     {
61         int v=fat[i];
62         if(v>0&&low[i]>dfn[v])//桥的条件
63             printf("%d, %d\n",i,v);
64     }
65 }
66 int main()
67 {
68     while(scanf("%d%d",&n,&m)!=EOF)
69     {
70         Init();
71         int a,b;
72         for(int i=1;i<=m;++i)
73         {
74             scanf("%d%d",&a,&b);
75             G[a].push_back(b);
76             G[b].push_back(a);
77         }
78         calc();
79     }
80     return 0;
81 }
View Code

求强连通缩点加拓扑排序。。。

 http://www.cnblogs.com/haoabcd2010/p/7419276.html

posted @ 2017-10-16 20:30  happy_codes  阅读(141)  评论(0编辑  收藏  举报