zoukankan      html  css  js  c++  java
  • POJ3177 Redundant Paths

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

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

    用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
    ",(leaves+1)/2);
        return 0;
    }
  • 相关阅读:
    composer 基本概念与常用命令总结
    慕课笔记-JavaScript正则表达式
    [网络编程]epoll的基础用法
    [C++学习笔记] const限定符
    boost库常用功能
    kafka C客户端librdkafka producer源码分析
    kafka 0.8.1 新producer 源码简单分析
    第一篇博客
    Jmeter连接数据库
    Jmeter录制APP脚本
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/12313421.html
Copyright © 2011-2022 走看看