zoukankan      html  css  js  c++  java
  • POJ3177_Redundant Paths

    给你一个无向图,求至少加入多少条边,使得整个图是双联通的。

    通过枚举题意,发现重边是不算的,直接去掉。

    首先把那些边是桥计算出来,把位于同一个连通分量里面的点缩成一个点(并查集),然后计算缩点后有多少个点的度数为1,只要处理这些点就好了。

    每次处理连接任意两个度数为1的点,增加一个联通分量,这样总共只要连接(n+1)/2次即可。

    召唤代码君:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <map>
    #define maxn 50050
    using namespace std;
    
    int f[maxn],g[maxn];
    int d[maxn],low[maxn],first[maxn];
    int to[maxn],next[maxn],edge=-1;
    bool c[maxn];
    int n,m,dfs_clock,ans;
    map<int, map<int,int> > ss;
    
    void _init()
    {
        dfs_clock=0;
        for (int i=1; i<=n; i++) d[i]=first[i]=-1,f[i]=i,g[i]=0;
    }
    
    void addedge(int U,int V)
    {
        c[++edge]=false;
        to[edge]=V,next[edge]=first[U],first[U]=edge;
        c[++edge]=false;
        to[edge]=U,next[edge]=first[V],first[V]=edge;
    }
    
    void dfs(int cur,int fa)
    {
        d[cur]=++dfs_clock,low[cur]=d[cur];
        for (int i=first[cur]; i!=-1; i=next[i])
        {
            if ((i^1)==fa || i==fa) continue;
            if (d[to[i]]==-1) dfs(to[i],i);
            low[cur]=min(low[cur],low[to[i]]);
        }
        if (fa!=-1 && low[cur]>=d[cur]) c[fa]=c[fa^1]=true;
    }
    
    int father(int x)
    {
        return f[x]==x?x:f[x]=father(f[x]);
    }
    
    int main()
    {
        int U,V;
        scanf("%d%d",&n,&m);
        _init();
        for (int i=1; i<=m; i++)
        {
            scanf("%d%d",&U,&V);
            if (U>V) swap(U,V);
            if (ss[U][V]) continue;
            addedge(U,V);
            ss[U][V]=1;
        }
        dfs(U,-1);
        
        for (int i=0; i<edge; i+=2)
        {
            if (c[i]) continue;
            int fx=father(to[i]),fy=father(to[i+1]);
            f[fx]=fy;
        }
        for (int i=0; i<edge; i+=2)
        {
            if (!c[i]) continue;
            int fx=father(to[i]),fy=father(to[i+1]);
            g[fx]++,g[fy]++;
        }
        
        for (int i=1; i<=n; i++) 
            if (g[i]==1) ans++;
        printf("%d
    ",(ans+1)/2);
        return 0;
    }
    如有转载,请注明出处(http://www.cnblogs.com/lochan)
  • 相关阅读:
    使用node.js搭建一个简单的后台服务
    node.js连接MySQL数据库
    js将date对象转换为指定格式
    配置angular2运行环境
    简单AJAX请求JSon数据
    正则表达式
    javascript typeof 和 instanceof 的区别和联系
    map和reduce函数的使用
    Github 上管理项目
    微服务资料
  • 原文地址:https://www.cnblogs.com/lochan/p/3844391.html
Copyright © 2011-2022 走看看