zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    MySQL next-key lock 加锁范围是什么?
    使用 Docker 安装并连接 MySQL
    Mac 常用软件推荐 —— Java 开发工程师
    Toolkit 大更新:UI 更美观,用起来更方便!
    工作中的设计模式 —— 建造者模式
    工作中的设计模式 —— 策略模式
    工作中的设计模式 —— 原型模式
    Centos7 安装Oracle记录
    Centos7 常用命令和自己平时使用命令
    AutoHotKey 简易自动化脚本的一些资料
  • 原文地址:https://www.cnblogs.com/zqy123/p/5978192.html
Copyright © 2011-2022 走看看