【图的连通性】poj2117Electricity

来源:互联网 发布:数据脱敏 指导 编辑:程序博客网 时间:2024/05/11 10:35

http://poj.org/problem?id=2117

题目描述:对一个无向图有n(n<=10000)个点m条边(不一定联通),可以删去任意一个点。求最大联通块数量。

这题题目很长,但有用的只有几句话。是不是很恶心……

这道题就是一个用tarjon算法求割点,注意割点是有相对性的。总而言之,是一道水题。

注意特判m=0的情况。

#include <iostream>#include <cstdio>#include <cstring>#define MAXN 10011#define MAXM 200000050using namespace std;struct node{    int v ;    node *next ;}edge[MAXM] ,*num[MAXN] ,*code=edge ;void add(int a,int b){    node *p=++code ;    p->v=b ,p->next=num[a] ;    num[a]=p ;}int n ,m ,rtson ,ans ,out ,a ,b ,cnt ,pos ;int low[MAXN] ,dfn[MAXN] ;void dfs(int u,int fa){    dfn[u]=low[u]=++cnt;    int v ,temp=0 ;    for(node *p=num[u];p!=NULL;p=p->next)        if((v=p->v)!=fa)        {            if(!dfn[v])            {                dfs(v,u);                low[u]=min(low[u],low[v]);                if(low[v]>=dfn[u])                {                    if(fa==-1)                        ++rtson;                    else ++temp;                }            }            else low[u]=min(low[u],dfn[v]);        }    ans=max(ans,temp+1);}int main(){    while(~scanf("%d%d",&n,&m)&&n+m)    {        if(m==0)        {            printf("%d\n",n-1);            continue;        }        memset(num,0,sizeof(num));        memset(dfn,0,sizeof(dfn));        memset(low,0,sizeof(low));        code=edge ,cnt=pos=ans=out=0 ;        for(int i=0;i<m;++i)        {            scanf("%d%d",&a,&b);            add(a,b);            add(b,a);        }        for(int i=0;i<n;++i)            if(!dfn[i])            {                ++pos;                rtson=0;                dfs(i,-1);                if(rtson>1)                    ans=max(ans,rtson);                out=max(out,ans);            }        printf("%d\n",pos+out-1);    }    return 0;}
0 0