tarjan跑出来所有的割点
dfs搞每一个点双和几个割点相连,0个就要建两个,因为建一个的话,那个地方没了就死了,1个就要建一个,因为如果割点断了,需要内部供给,2个就不用建,任意一个断都可以从另一边过
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<cmath> 6 #define N 1500 7 using namespace std; 8 int n,m,cnt,num,tot,ans1,cosmos,bo[N]; 9 long long ans2; 10 int dfn[N],low[N],judge[N],top,son,root; 11 int e=1,head[N]; 12 struct edge{ 13 int u,v,next; 14 }ed[5000]; 15 void add(int u,int v){ 16 ed[e].u=u; ed[e].v=v; 17 ed[e].next=head[u]; head[u]=e++; 18 } 19 void tarjan(int x,int f){ 20 dfn[x]=low[x]=++top; 21 for(int i=head[x];i;i=ed[i].next){ 22 int v=ed[i].v; 23 if(v==x) continue; 24 if(!dfn[v]){ 25 tarjan(v,x); 26 low[x]=min(low[x],low[v]); 27 } 28 else{low[x]=min(low[x],dfn[v]);continue;} 29 if(dfn[x]<=low[v]){ 30 if(x==root)son++; 31 else judge[x]=1; 32 } 33 } 34 } 35 void dfs(int x){ 36 bo[x]=tot; 37 if(judge[x]) return;cnt++; 38 for(int i=head[x];i;i=ed[i].next){ 39 int v=ed[i].v; 40 if(judge[v]&&bo[v]!=tot){num++;bo[v]=tot;} 41 if(!bo[v])dfs(v); 42 } 43 } 44 void init(){ 45 memset(dfn,0,sizeof dfn); 46 memset(low,0,sizeof low); 47 memset(judge,0,sizeof judge); 48 memset(bo,0,sizeof bo); cosmos++; 49 n=0; ans1=0; ans2=1; tot=0; top=0; 50 e=1; memset(head,0,sizeof head); 51 } 52 int main(){ 53 while(scanf("%d",&m)==1&&m!=0){ 54 init(); 55 int u,v; 56 for(int i=1;i<=m;i++){ 57 scanf("%d%d",&u,&v); 58 n=max(n,max(u,v)); 59 add(u,v); add(v,u); 60 } 61 for(int i=1;i<=n;i++){ 62 if(!dfn[i]){ 63 son=0; root=i; 64 tarjan(i,0); 65 if(son>1) judge[i]=1; 66 } 67 } 68 /*for(int i=1;i<=n;i++) 69 printf("%d %d ",i,judge[i]);*/ 70 for(int i=1;i<=n;i++){ 71 if(!bo[i]&&!judge[i]){ 72 tot++;cnt=num=0; 73 dfs(i); 74 if(!num){ans1+=2;ans2*=cnt*(cnt-1)/2;} 75 if(num==1){ans1++;ans2*=cnt;} 76 //printf("%d %d %d %d ",i,tot,cnt,num); 77 } 78 } 79 printf("Case %d: %d %lld ",cosmos,ans1,ans2); 80 } 81 return 0; 82 }