Description
Input
输入文件有若干组数据,每组数据的第一行是一个正整数 N(N≤500),表示工地的隧道数,接下来的 N 行每行是用空格隔开的两个整数 S 和 T,表示挖 S 与挖煤点 T 由隧道直接连接。输入数据以 0 结尾。
Output
输入文件中有多少组数据,输出文件 output.txt 中就有多少行。每行对应一组输入数据的 结果。其中第 i 行以 Case i: 开始(注意大小写,Case 与 i 之间有空格,i 与:之间无空格,: 之后有空格),其后是用空格隔开的两个正整数,第一个正整数表示对于第 i 组输入数据至少需 要设置几个救援出口,第二个正整数表示对于第 i 组输入数据不同最少救援出口的设置方案总 数。输入数据保证答案小于 2^64。输出格式参照以下输入输出样例。
Sample Input
1 3
4 1
3 5
1 2
2 6
1 5
6 3
1 6
3 2
6
1 2
1 3
2 4
2 5
3 6
3 7
0
Sample Output
Case 2: 4 1
HINT


#include<cstdio> #include<cstring> #include<algorithm> #define LL long long using std::max; using std::min; const int M=1e3+7; int read(){int ans=0,f=1,c=getchar();while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}return ans*f; } int n,m; int first[M],cnt,buck[M]; struct node{int from,to,next;}e[2*M]; void ins(int a,int b){e[++cnt]=(node){a,b,first[a]}; first[a]=cnt;} void insert(int a,int b){ins(a,b); ins(b,a);} int dfn[M],low[M],T,iscut[M]; int hc,sz[M],color[M],stk[M],top; void clear(){n=0; cnt=1; T=0; hc=0; top=0;memset(iscut,0,sizeof(iscut));memset(first,0,sizeof(first));memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low));memset(sz,0,sizeof(sz));memset(color,0,sizeof(color));memset(buck,0,sizeof(buck)); } void tarjan(int x,int fa){low[x]=dfn[x]=++T;int child=0;for(int i=first[x];i;i=e[i].next){int now=e[i].to;if(!dfn[now]){stk[++top]=i;child++;tarjan(now,x);low[x]=min(low[x],low[now]);if(low[now]>=dfn[x]){iscut[x]=1;hc++;while(1){int k=stk[top--];if(color[e[k].from]!=hc){if(color[e[k].from]) buck[color[e[k].from]]++;sz[hc]++; color[e[k].from]=hc;}if(color[e[k].to]!=hc){if(color[e[k].to]) buck[color[e[k].to]]++;sz[hc]++; color[e[k].to]=hc;}if(e[k].from==x&&e[k].to==now) break;}}}else if(dfn[now]<dfn[x]&&now!=fa) stk[++top]=i,low[x]=min(low[x],dfn[now]);}if(fa==-1&&child==1) iscut[x]=0; } int main(){int x,y,h=0;while(scanf("%d",&m)==1&&m){++h; clear();for(int i=1;i<=m;i++){x=read(); y=read();insert(x,y); n=max(n,max(x,y));}for(int i=1;i<=n;i++)if(!dfn[i]) tarjan(i,-1);for(int i=1;i<=n;i++)if(iscut[i]) buck[color[i]]++;LL ans=1;int tot=0;for(int i=1;i<=hc;i++){if(buck[i]==1) ans*=max(sz[i]-1,1),tot++;if(!buck[i]) ans*=sz[i]*(sz[i]-1)/2,tot+=2;}printf("Case %d: %d %lld\n",h,tot,ans);}return 0; }