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;

}

 

你可能感兴趣的:(struct)