zoukankan      html  css  js  c++  java
  • POJ 3177 Redundant Paths(边双连通分量)

     

    题目大意

     

    给了一个有 n(1<=n<=5000) 个点 m(n-1<=m<=10000) 个边的连通的无向图,现在问最少需要添加多少条边才能使得整个图中所有的点对之间至少存在两条没有交集的路径?

    有一个坑就是,给的无向图中有可能有重边,但是重边的话只能算一条边

     

    做法分析

     

    根据题意可以知道,这题要求一个边双连通分量,求出边双连通分量之后,得到一棵树,找出所有书中度为 1 的点的个数 num,我们添加边肯定是在度为 1 的点之间添加,那么,最少要添加的边的数量不难想到是:(num+1)/2

     

    参考代码

    POJ 3177
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <vector>
     5 #include <stack>
     6 #include <algorithm>
     7 
     8 using namespace std;
     9 
    10 const int N=5006;
    11 
    12 vector <int> arc[N];
    13 int dfn[N], low[N], id[N];
    14 bool vs[N];
    15 stack <int> s;
    16 int n, m, ind, T;
    17 
    18 void tarjan(int u, int pre)
    19 {
    20     dfn[u]=low[u]=T++;
    21     s.push(u), vs[u]=1;
    22     int len=(int)arc[u].size(), last=-1;
    23     for(int i=0; i<len; i++)
    24     {
    25         int v=arc[u][i];
    26         if(pre==v || v==last) continue;
    27         last=v;
    28         if(dfn[v]==-1)
    29         {
    30             tarjan(v, u);
    31             if(low[u]>low[v]) low[u]=low[v];
    32         }
    33         else if(vs[v] && low[u]>dfn[v]) low[u]=dfn[v];
    34     }
    35     if(low[u]==dfn[u])
    36     {
    37         for(int v; 1; )
    38         {
    39             v=s.top();
    40             vs[v]=0, s.pop();
    41             id[v]=ind;
    42             if(v==u) break;
    43         }
    44         ind++;
    45     }
    46 }
    47 
    48 int main()
    49 {
    50     scanf("%d%d", &n, &m);
    51     for(int i=1; i<=n; i++) arc[i].clear();
    52     for(int i=0, a, b; i<m; i++)
    53     {
    54         scanf("%d%d", &a, &b);
    55         arc[a].push_back(b);
    56         arc[b].push_back(a);
    57     }
    58     for(int i=1; i<=n; i++) sort(arc[i].begin(), arc[i].end());
    59     for(int i=1; i<=n; i++) dfn[i]=-1, vs[i]=0;
    60     while(!s.empty()) s.pop();
    61     ind=T=0;
    62     for(int i=1; i<=n; i++) if(dfn[i]==-1) tarjan(i, -1);
    63     for(int i=0; i<ind; i++) dfn[i]=0;
    64     for(int i=1; i<=n; i++)
    65     {
    66         int u=id[i], len=(int)arc[i].size(), last=-1;
    67         for(int j=0; j<len; j++)
    68         {
    69             if(arc[i][j]==last) continue;
    70             last=arc[i][j];
    71             int v=id[arc[i][j]];
    72             if(u!=v) dfn[u]++, dfn[v]++;
    73         }
    74     }
    75     int cnt=0;
    76     for(int i=0; i<ind; i++) if(dfn[i]==2) cnt++;
    77     printf("%d\n", (cnt+1)/2);
    78     return 0;
    79 }

    AC通道

    POJ 3177 Redundant Paths

  • 相关阅读:
    【题解】JSOI2009游戏
    【考试记录】4.8 Path (网络流 —— 劲题)
    【考试记录】4.8 Table ( 数论数学 --组合数 & 杨辉三角)
    【题解】HNOI2016树
    【算法】最小乘积生成树 & 最小乘积匹配 (HNOI2014画框)
    【加油!】
    [bzoj4916] 神犇和蒟蒻 [杜教筛]
    [CQOI2015][bzoj3930] 选数 [杜教筛+莫比乌斯反演]
    [luogu3768] 简单的数学题 [杜教筛]
    春季学习记录
  • 原文地址:https://www.cnblogs.com/zhj5chengfeng/p/2974508.html
Copyright © 2011-2022 走看看