码迷,mamicode.com
首页 > 其他好文 > 详细

POJ3177 Redundant Paths

时间:2020-02-15 20:37:22      阅读:66      评论:0      收藏:0      [点我收藏+]

标签:leave   max   div   vector   while   pop   增加   int   tin   

双连通图:无向图中每两个顶点都存在完全不同的两条路径

给定一个无向图,问要给它增加多少条边可以把它变成双连通图。

用tarjan缩点,可以得到一棵树,添加(叶子结点+1)/2条边可以使其成环,也就是答案~

为了避开重边,这题用邻接矩阵存,wa了一晚上QAQ~

#include<cstdio>
#include<algorithm>
#include<vector>
#include<stack>
using namespace std;
const int maxn=5014;
int g[maxn][maxn];
int N,M,x,y;
int low[maxn];
int dfn[maxn];
stack<int> st;
int cnt;
int scc;
int pos[maxn];
int in[maxn];
void tarjan (int x,int pre) {
    low[x]=dfn[x]=++cnt;
    st.push(x);
    for (int i=1;i<=N;i++) {
        if (i==pre) continue;
        if (!g[x][i]) continue;
        if (!low[i]) {
            tarjan(i,x);
            low[x]=min(low[x],low[i]);
        }
        else if (!pos[i]) low[x]=min(low[x],dfn[i]);
    }
    if (low[x]==dfn[x]) {
        scc++;
        while (1) {
            int u=st.top();
            st.pop();
            low[u]=low[x];
            pos[u]=scc;
            if (u==x) break;
        }
    }
}
void build () {
    for (int i=1;i<=N;i++) {
        for (int j=1;j<=N;j++) {
            if (pos[i]!=pos[j]&&g[i][j]) in[pos[j]]++;
        }
    }
}
int main () {
    scanf ("%d %d",&N,&M);
    for (int i=0;i<M;i++) {
        scanf ("%d %d",&x,&y);
        g[x][y]=g[y][x]=1;
    }
    for (int i=1;i<=N;i++) 
    if (!low[i]) tarjan(i,i);
    build ();
    int leaves=0;
    for (int i=1;i<=scc;i++) {
        if (in[i]==1) leaves++;
    }
    printf ("%d\n",(leaves+1)/2);
    return 0;
}

 

POJ3177 Redundant Paths

标签:leave   max   div   vector   while   pop   增加   int   tin   

原文地址:https://www.cnblogs.com/zhanglichen/p/12313421.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!