bzoj2730 [HNOI2012] 矿场搭建

来源:互联网 发布:战舞幻想曲礼物数据 编辑:程序博客网 时间:2024/04/30 07:35

tarjan跑出来所有的割点

dfs搞每一个点双和几个割点相连,0个就要建两个,因为建一个的话,那个地方没了就死了,1个就要建一个,因为如果割点断了,需要内部供给,2个就不用建,任意一个断都可以从另一边过

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<cmath>#define N 1500using namespace std;int n,m,cnt,num,tot,ans1,cosmos,bo[N];long long ans2;int dfn[N],low[N],judge[N],top,son,root;int e=1,head[N];struct edge{    int u,v,next;}ed[5000];void add(int u,int v){    ed[e].u=u; ed[e].v=v;    ed[e].next=head[u]; head[u]=e++;}void tarjan(int x,int f){    dfn[x]=low[x]=++top;    for(int i=head[x];i;i=ed[i].next){        int v=ed[i].v;        if(v==x) continue;        if(!dfn[v]){            tarjan(v,x);            low[x]=min(low[x],low[v]);        }        else{low[x]=min(low[x],dfn[v]);continue;}        if(dfn[x]<=low[v]){            if(x==root)son++;            else judge[x]=1;        }    }}void dfs(int x){    bo[x]=tot;    if(judge[x]) return;cnt++;    for(int i=head[x];i;i=ed[i].next){        int v=ed[i].v;        if(judge[v]&&bo[v]!=tot){num++;bo[v]=tot;}        if(!bo[v])dfs(v);    }}void init(){    memset(dfn,0,sizeof dfn);    memset(low,0,sizeof low);    memset(judge,0,sizeof judge);    memset(bo,0,sizeof bo); cosmos++;    n=0; ans1=0; ans2=1; tot=0; top=0;    e=1; memset(head,0,sizeof head);}int main(){    while(scanf("%d",&m)==1&&m!=0){        init();        int u,v;        for(int i=1;i<=m;i++){            scanf("%d%d",&u,&v);            n=max(n,max(u,v));            add(u,v); add(v,u);        }        for(int i=1;i<=n;i++){            if(!dfn[i]){                son=0; root=i;                 tarjan(i,0);                if(son>1) judge[i]=1;            }        }        /*for(int i=1;i<=n;i++)            printf("%d  %d\n",i,judge[i]);*/        for(int i=1;i<=n;i++){            if(!bo[i]&&!judge[i]){                tot++;cnt=num=0;                dfs(i);                if(!num){ans1+=2;ans2*=cnt*(cnt-1)/2;}                if(num==1){ans1++;ans2*=cnt;}                //printf("%d  %d  %d  %d\n",i,tot,cnt,num);            }        }        printf("Case %d: %d %lld\n",cosmos,ans1,ans2);    }    return 0;}


原创粉丝点击