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

poj3177 Redundant Paths 边双连通分量

时间:2014-07-03 16:59:36      阅读:226      评论:0      收藏:0      [点我收藏+]

标签:blog   os   2014   for   io   amp   



#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#define inf 0x3f3f3f3f
#define eps 1e-6
#define ll __int64
using namespace std;
#define N 1010
#define M 20010

struct node
{
    int v;//下个顶点
    node *next;//下个边结点
};
int n,m,r[N],d[N];//d表示缩点后各顶点的度数
node mem[M];int memp;//存储边结点
node *e[N];
int necc;//原图中边双连通分量的个数
int belong[N];
int low[N],dfn[N];
int vis[N];
int brig[M][2],nbrig;

void addedge(int i,int j)
{
    node *p=&mem[memp++];
    p->v=j;
    p->next=e[i];
    e[i]=p;
}

int root(int a)
{
    if(a!=r[a])
        r[a]=root(r[a]);
    return r[a];
}

void merge(int a,int b)
{
    int ra=root(a);
    int rb=root(b);
    if(ra!=rb)
        r[ra]=rb;
}

void dfs(int i,int father,int dth)
{
    int j,tofa=0;
    node *p;
    vis[i]=1;
    low[i]=dfn[i]=dth;
    for(p=e[i];p!=NULL;p=p->next)
    {
        j=p->v;
        if(vis[j]&&(j!=father||tofa))
            low[i]=min(low[i],dfn[j]);
        if(!vis[j])
        {
            dfs(j,i,dth+1);
            low[i]=min(low[i],low[j]);
            if(low[j]<=dfn[i]) merge(i,j);//i,j在同一个双联通分量
            if(low[j]>dfn[i]) //边i,j是桥
            {
                brig[nbrig][0]=i;
                brig[nbrig++][1]=j;
            }
        }
        if(j==father) tofa=1;
    }
    vis[i]=2;
}

int doubleconne()
{
    int i,k,ncon=nbrig=0;
    dfs(0,-1,1);
    for(i=0;i<n;i++)
    {
        k=root(i);
        if(belong[k]==-1) belong[k]=ncon++;
        belong[i]=belong[k];
    }
    return ncon;
}

void init()
{
    memp=nbrig=0;
    memset(e,0,sizeof e);
    memset(d,0,sizeof d);
    for(int i=0;i<=n;i++)
        r[i]=i;
    memset(vis,0,sizeof vis);
    memset(belong,-1,sizeof belong);
}

int main()
{
    int i,j,k,a,b;
    while(~scanf("%d%d",&n,&m))
    {
        init();
        for(i=0;i<m;i++)
        {
            scanf("%d%d",&a,&b);
            addedge(a-1,b-1);
            addedge(b-1,a-1);
        }
        necc=doubleconne();
        for(k=0;k<nbrig;k++)
        {
            i=brig[k][0];
            j=brig[k][1];
            d[belong[i]]++;
            d[belong[j]]++;
        }
        int cnt=0;//收缩后叶子结点的个数
        for(i=0;i<necc;i++)
            if(d[i]==1) cnt++;
        printf("%d\n",(cnt+1)/2);
    }
    return 0;
}



poj3177 Redundant Paths 边双连通分量,布布扣,bubuko.com

poj3177 Redundant Paths 边双连通分量

标签:blog   os   2014   for   io   amp   

原文地址:http://blog.csdn.net/u011032846/article/details/36466627

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