HDU4738 tarjan割边|割边、割点模板

题目:http://acm.hdu.edu.cn/showproblem.php?pid=4738

坑点:

  1. 处理重边
  2. 图可能不连通,要输出0
  3. 若求出的结果是0,则要输出1,因为最少要派一个人
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 1111;
 4 const int inf = 0x3f3f3f3f;
 5 struct edge{
 6     int to,cost;
 7 };
 8 vector<edge> g[maxn];
 9 int num[maxn],low[maxn],index;
10 int res;
11 int mp[maxn][maxn];//处理两点之间边的条数 
12 //tarjan 
13 void tarjan(int cur,int father){
14     index++;
15     num[cur] = index;
16     low[cur] = index;
17     for(int i = 0;i<g[cur].size();i++){
18         if(num[g[cur][i].to] == 0){
19             tarjan(g[cur][i].to,cur);
20             low[cur] = min(low[g[cur][i].to],low[cur]);
21             if(low[g[cur][i].to] > num[cur] && mp[cur][g[cur][i].to] == 1)
22                 res = min(res,g[cur][i].cost);
23         }else if(g[cur][i].to != father){
24             low[cur] = min(low[cur],num[g[cur][i].to]);
25         }
26     }
27 }
28 //并查集判断连通性 
29 int f[maxn];
30 int getf(int x){
31     if(f[x] == x){
32         return x;
33     }else{
34         return f[x] = getf(f[x]);
35     }
36 }
37 int merge(int l,int r){
38     int a = getf(l);
39     int b = getf(r);
40     if(a != b){
41         f[a] = b;
42     }
43 }
44 // 初始化 
45 void init(int n){
46     index = 0;
47     res = inf;
48     memset(num,0,sizeof(num));
49     memset(low,0,sizeof(low));
50     memset(mp,0,sizeof(mp));
51     for(int i = 1;i<=n;i++){
52         g[i].clear();
53         f[i] = i;
54     }
55 }
56 int main(){  
57     int n,m;
58     while(scanf("%d%d",&n,&m) && n && m){
59         init(n);
60         int a,b,c;
61         while(m--){
62             scanf("%d%d%d",&a,&b,&c);
63             g[a].push_back(edge{b,c});
64             g[b].push_back(edge{a,c});
65             merge(a,b);
66             mp[a][b]++;
67             mp[b][a]++;
68         }
69         int flag = 0;
70         for(int i = 1;i<=n;i++)
71             if(getf(i) != getf(1)){
72                 flag = 1;
73                 break;
74             }
75         if(flag){
76             puts("0");
77             continue;
78         }
79         tarjan(1,1);
80         if(res == 0)
81             res++;
82         if(res == inf)
83             puts("-1");
84         else
85             printf("%d
",res);
86     }
87     return 0;  
88 }  
View Code

割边模板:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 1111;
 4 const int inf = 0x3f3f3f3f;
 5 struct edge{
 6     int to,cost;
 7 };
 8 vector<edge> g[maxn];
 9 int num[maxn],low[maxn],index;
10 //tarjan 
11 void tarjan(int cur,int father){
12     index++;
13     num[cur] = index;
14     low[cur] = index;
15     for(int i = 0;i<g[cur].size();i++){
16         if(num[g[cur][i].to] == 0){
17             tarjan(g[cur][i].to,cur);
18             low[cur] = min(low[g[cur][i].to],low[cur]);
19             if(low[g[cur][i].to] > num[cur])
20                 //u-v为割边 
21         }else if(g[cur][i].to != father){
22             low[cur] = min(low[cur],num[g[cur][i].to]);
23         }
24     }
25 }
26 // 初始化 
27 void init(int n){
28     memset(num,0,sizeof(num));
29     memset(low,0,sizeof(low));
30     for(int i = 1;i<=n;i++){
31         g[i].clear();
32     }
33 }
View Code

割点模板:

 1 const int maxn = 1111;
 2 const int inf = 0x3f3f3f3f;
 3 struct edge{
 4     int to,cost;
 5 };
 6 vector<edge> g[maxn];
 7 int num[maxn],low[maxn],index;
 8 //tarjan 
 9 void tarjan(int cur,int father){
10     int child = 0; 
11     index++;
12     num[cur] = index;
13     low[cur] = index;
14     for(int i = 0;i<g[cur].size();i++){
15         if(num[g[cur][i].to] == 0){
16             child++;
17             tarjan(g[cur][i].to,cur);
18             low[cur] = min(low[g[cur][i].to],low[cur]);
19             if(low[g[cur][i].to] >= num[cur] && cur!=root)
20                 //cur为割点
21             if(cur==root && child>=2)
22                 //cur为割点 
23         }else if(g[cur][i].to != father){
24             low[cur] = min(low[cur],num[g[cur][i].to]);
25         }
26     }
27 }
28 // 初始化 
29 void init(int n){
30     memset(num,0,sizeof(num));
31     memset(low,0,sizeof(low));
32     for(int i = 1;i<=n;i++){
33         g[i].clear();
34     }
35 }
View Code
原文地址:https://www.cnblogs.com/zqy123/p/5978192.html