您的位置:首页 > 其它

poj 2117 求割点+联通分量个数

2015-06-15 10:50 288 查看
p个点,c条边的无向图中求去掉1个点后最多形成的连通分量个数。

1、若c=0,结果即为p-1

2、否则,结果为初始连通分量个数+最大割边数

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cstring>
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<vector>
using namespace std;

typedef unsigned __int64 uLL;
typedef __int64 LL;
typedef double db;

struct P{
    int to,next;
}edge[40005];
int head[10005],cnt,dfs_clock,pre[10005],ans[10005];

void add(int u,int v)
{
    edge[cnt].to=v;
    edge[cnt].next=head[u];
    head[u]=cnt++;
}
int r;
int dfs(int u,int fa)
{
    int lowu=pre[u]=++dfs_clock,child=0;
    for(int i=head[u];~i;i=edge[i].next)
    {
        int v=edge[i].to;
        if(!pre[v])
        {
            ++child;
            int lowv=dfs(v,u);
            lowu=min(lowu,lowv);
            if((u!=r&&lowv>=pre[u])||(u==r&&child>1)) ++ans[u];
        }
        else if(pre[v]<pre[u]&&v!=fa) lowu=min(lowu,pre[v]);
    }
    //if(fa<0&&child==1) ans[u]=0;
    return lowu;
}
int main()
{
    int i,P,C;
    while(~scanf("%d%d",&P,&C)&&(P+C))
    {
        if(C==0) {printf("%d\n",P-1);continue;}
        cnt=dfs_clock=0;
        memset(pre,0,sizeof(pre));
        memset(ans,0,sizeof(ans));
        memset(head,-1,sizeof(head));
        for(i=1;i<=C;++i)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            add(x,y);
            add(y,x);
        }
        int s=-1,tot=0;
        for(i=0;i<P;++i)
        {
            if(!pre[i])
            {
                r=i;
                dfs(i,-1);
                ++tot;
            }
            s=max(s,ans[i]);
        }
        printf("%d\n",tot+s);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: