记录编号 436422 评测结果 AAAAAAAAAA
题目名称 1348.[HNOI 2012] 矿场搭建 最终得分 100
用户昵称 BaDBoY 是否通过 通过
代码语言 C++ 运行时间 0.000 s
提交时间 2017-08-11 20:39:25 内存使用 0.00 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 505
int read() {
	int s=0,f=1;
	char ch=getchar();
	while(ch>'9'||ch<'0') {
		if(ch=='-') {
			f=-1;
		}
		ch=getchar();
	}
	while(ch>='0'&&ch<='9') {
		s=(s<<1)+(s<<3)+(ch^48);
		ch=getchar();
	}
	return s*f;
}
long long ji,nn;
int kk,T,cnt,mx,belong[505],num[505],n,tot,r[505],dfn[505],low[505],tim,fa[505];
bool conn[505][505],is_cut[505];
struct edge {
	int to,next;
} c[250005];
void add(int x,int y) {
	c[tot]=(edge) {
		y,r[x]
	};
	r[x]=tot++;
}
void clean() {
	kk=T=nn=ji=mx=cnt=tot=tim=0;
	memset(r,-1,sizeof(r));
	memset(c,0,sizeof(c));
	memset(dfn,-1,sizeof(dfn));
	memset(low,0,sizeof(low));
	memset(fa,0,sizeof(fa));
	memset(is_cut,false,sizeof(is_cut));
	memset(num,0,sizeof(num));
	memset(belong,0,sizeof(belong));
}
class oo {
	public:
		void work() {
			tarjan(1,-1);
			int root=0;
			for(int i=2; i<=mx; ++i) {
				int v=fa[i];
				if(v==1) {
					++root;
				} else {
					if(low[i]>=dfn[v]&&v) {
						is_cut[v]=true;
						++kk;
					}
				}
			}
			if(root>1) {
				is_cut[1]=true;
				++kk;
			}
		}
	private:
		void tarjan(int x,int f) {
			fa[x]=f;
			dfn[x]=low[x]=tim++;
			for(int i=r[x]; ~i; i=c[i].next) {
				if(dfn[c[i].to]==-1) {
					tarjan(c[i].to,x);
					low[x]=min(low[x],low[c[i].to]);
				} else {
					if(c[i].to!=f) {
						low[x]=min(low[x],dfn[c[i].to]);
					}
				}
			}
		}
} cut_point;
int hh;
void dfs(int x) {
	belong[x]=T;
	if(is_cut[x]) return;
	nn++;
	for(int i=r[x]; ~i; i=c[i].next) {
		if (is_cut[c[i].to]&&belong[c[i].to]!=T) {
			ji++,belong[c[i].to]=T;
		}
		if (!belong[c[i].to]) {
			dfs(c[i].to);
		}
	}
}
int Main(){
	freopen("bzoj_2730.in","r",stdin);
	freopen("bzoj_2730.out","w",stdout);
	while(~scanf("%d",&n)&&n) {
		clean();
		for(int x,y,i=1; i<=n; ++i) {
			x=read(),y=read();
			add(x,y),add(y,x);
			mx=max(mx,max(x,y));
		}
		cut_point.work();
		if(!kk) {
			int ans1=2;
			long long ans2=mx*(mx-1)/2;
			hh++;
			printf("Case %d: %d %lld\n",hh,ans1,ans2);
			continue;
		}
		int ans1=0;
		long long ans2=1;
		for (int i=1; i<=mx; i++){
			if(!belong[i]&&!is_cut[i]) {
				++T;
				ji=nn=0;
				dfs(i);
				if(!ji) {
					ans1+=2;
					ans2*=nn*(nn-1)/2;
				}
				if(ji==1) {
					ans1++;
					ans2*=nn;
				}
			}
		}
		hh++;
		printf("Case %d: %d %lld\n",hh,ans1,ans2);
	}
	return 0;
}
int hehe=Main();
int main(){
	;
}