POJ 3352 Road Construction (双连通缩点)

题目大意:给定一个无向连通图,求至少需添加几条边,使得原图双连通(不存在桥)。

分析:用tarjan算法找桥,将所有不是桥的边的端点用并查集合并,这题以前写过,至于为什么可以用并查集来合并,可以参考以前那篇博客

需要注意的是,数据中有重边,在判桥时要注意。可以用一个矩阵存储边的数目,若某边数目大于1,则一定不是桥。

View Code
#include <stdio.h>
#include <string.h>
#define MIN(a,b) ((a)<(b)?(a):(b))
#define N 1001
#define M 2002
int n,m,e;
int g[N][N];
int first[N],next[M],v[M];
int dfn[N],low[N],id[N],cnt;
int p[N];
int d[N];
void make_set()
{
    for(int i=1;i<=n;i++)   p[i]=i;
}
int find_set(int i)
{
    if(i^p[i])  p[i]=find_set(p[i]);
    return p[i];
}
void union_set(int i,int j)
{
    i=find_set(i),j=find_set(j);
    if(i^j) p[j]=i;
}
void init()
{
    e=0;
    memset(first,-1,sizeof(int)*(n+1));
    cnt=0;
    memset(dfn,0,sizeof(int)*(n+1));
    for(int i=1;i<=n;i++)   memset(g[i],0,sizeof(int)*(n+1));
}
void insert(int a,int b)
{
    v[e]=b;
    next[e]=first[a];
    first[a]=e++;
    g[a][b]++;
}
void dfs(int a,int fa)
{
    int i,b;
    dfn[a]=low[a]=++cnt;
    for(i=first[a];i!=-1;i=next[i])
    {
        b=v[i];
        if(dfn[b] && b!=fa)  low[a]=MIN(low[a],dfn[b]);
        else if(!dfn[b])
        {
            dfs(b,a);
            low[a]=MIN(low[b],low[a]);
            if(low[b]<=dfn[a] || g[a][b]>1)
            {
                union_set(a,b);
            }
        }
    }
}
void solve()
{
    int a,b,i,pi,k=0;
    dfs(1,0);
    memset(id,-1,sizeof(id));
    for(i=1;i<=n;i++)
    {
        pi=find_set(i);
        if(id[pi]==-1)  id[pi]=k++;
    }
    memset(d,0,sizeof(d));
    for(a=1;a<=n;a++)
    {
        for(i=first[a];i!=-1;i=next[i])
        {
            b=v[i];
            if(find_set(a)^find_set(b)) d[id[p[a]]]++,d[id[p[b]]]++;
        }
    }
    int ans=0;
    for(i=0;i<k;i++)    if(d[i]==2) ans++;
    printf("%d\n",(ans+1)/2);
}
int main()
{
    int a,b;
    while(~scanf("%d%d",&n,&m))
    {
        init();
        make_set();
        while(m--)
        {
            scanf("%d%d",&a,&b);
            insert(a,b);
            insert(b,a);
        }
        solve();
    }
    return 0;
}

 

posted @ 2012-07-26 22:48  BeatLJ  阅读(184)  评论(0编辑  收藏  举报