Hoj 1789 Electricity

来源:互联网 发布:php权限管理源代码 编辑:程序博客网 时间:2024/05/21 05:22

题目链接:http://acm.hit.edu.cn/hoj/problem/view?id=1789

题目大意:在一个无向图中,删除某一个点所形成的最大连通分量数目是多少。

我们知道,删除一个点某个图的连通分量增加,那么这个点是割点。

我们用cutNum[u]保存u这个点所关联的连通分量的数目。其中的最大值加上原图中

的连通分量的数目就是答案。

注意边数如果是0的话,要特判一下,此时去掉某一点连通分量数是n-1

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include <stack>#include <queue>#include <algorithm>#include <iostream>using namespace std;#define Maxn 10005#define Maxm 500005int dfn[Maxn];int low[Maxn];int dfs_clock;int scc_cnt;int root;int n;int total = 0;int first[Maxn];int next[Maxm];struct Edge{    int a,b;}edge[Maxm];int cutNum[Maxn];void addEdge(int a,int b){    edge[total].a =a ,edge[total].b = b;    next[total] = first[a];    first[a] = total++;}void init(){    total = 0;    memset(first,-1,sizeof(first));}void tarjan(int u){    dfn[u] = low[u] = ++dfs_clock;    int cnt = 0;    for(int i=first[u];i!=-1;i=next[i])    {        int v = edge[i].b;        if(!dfn[v])        {            tarjan(v);            cnt++;            low[u] = min(low[u],low[v]);            if( (u == root && cnt>1) || (u!=root && dfn[u]<=low[v]) )         {        cutNum[u]++;        }        }        else        {            low[u] = min(low[u],dfn[v]);        }    }}int cutPoint(int n){int sum = 0;    dfs_clock = 0;    memset(dfn,0,sizeof(dfn));    memset(low,0,sizeof(low));    memset(cutNum,0,sizeof(cutNum));    //如果是非连通图,就得用for循环了    //如果是连通图,root=1,tarjan(1)即可    for(int i=1;i<=n;i++)    {        if(!dfn[i]) sum++,root = i,tarjan(i);    }    int ans = 0;    for(int i=1;i<=n;i++)    {    ans = max(cutNum[i],ans);    }    return ans+sum;}int main(){    #ifndef ONLINE_JUDGE        freopen("in.txt","r",stdin);    #endif        int p,c;        int a,b;        while(scanf(" %d %d",&p,&c)!=EOF)        {        if(p == 0 && c == 0) break;        if(c == 0)         {        printf("%d\n",p-1 );        continue;        }        init();        for(int i=0;i<c;i++)        {            scanf(" %d %d",&a,&b);            a++,b++;            addEdge(a,b);            addEdge(b,a);        }        int ans = cutPoint(p);        printf("%d\n",ans);        }    return 0;}


原创粉丝点击