• 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

  • 相关阅读:
    go 学习笔记---chan
    golang学习笔记---Goroutine
    golang ---Learn Concurrency
    golang ----并发 && 并行
    golang 学习笔记 使用cmd
    并发程序与并行程序
    golang学习笔记 ---interface
    golang --- map如何判断key是否存在
    golang学习 ---defer语句
    golang --for语句
  • 原文地址:https://www.cnblogs.com/zhj5chengfeng/p/2974508.html
Copyright © 2020-2023  润新知