首页 > 代码库 > codevs 1996 矿场搭建
codevs 1996 矿场搭建
1996 矿场搭建
时间限制: 1 s
空间限制: 256000 KB
题目等级 : 大师 Master
题目描述 Description
煤矿工地可以看成是由隧道连接挖煤点组成的无向图。为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处。于是矿主决定在某些挖煤点设立救援出口,使得无论哪一个挖煤点坍塌之后,其他挖煤点的工人都有一条道路通向救援出口。
请写一个程序,用来计算至少需要设置几个救援出口,以及不同最少救援出口的设置方案总数。
输入描述 Input Description
输入文件有若干组数据,每组数据的第一行是一个正整数N(N≤500),表示工地的隧道数,接下来的N 行每行是用空格隔开的两个整数S 和T,表示挖煤点S 与挖煤点T 由隧道直接连接。输入数据以0 结尾。
输出描述 Output Description
输入文件中有多少组数据,输出文件中就有多少行。每行对应一组输入数据的结果。其中第i 行以Case i: 开始(注意大小写,Case 与i 之间有空格,i 与:之间无空格,:之后有空格),其后是用空格隔开的两个正整数,第一个正整数表示对于第i 组输入数据至少需要设置几个救援出口,第二个正整数表示对于第i 组输入数据不同最少救援出口的设置方案总数。输入数据保证答案小于2^64。输出格式参照以下输入输出样例。
样例输入 Sample Input
9
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 1: 2 4
Case 2: 4 1
数据范围及提示 Data Size & Hint
Case 1 的四组解分别是(2,4),(3,4),(4,5),(4,6);
Case 2 的一组解为(4,5,6,7)。
/*额 刚开始求得缩点后度为1的结果不对比如 缩完点后只有一个点等正解先求出割点 割点将其他的分成很多部分这些部分连着2个以上割点的不用建 连着1个割点的要建一个连着0个割点的要建两个 */#include<iostream>#include<cstdio>#include<cstring>#define LL long long#define maxn 510using namespace std;LL n,m,topt,tot,anst,answ,sum;LL first[maxn];LL dfn[maxn],low[maxn];LL c[maxn],f[maxn],p[maxn],num[maxn];struct edge{ LL to; LL next;}e[maxn*2];LL init(){ LL x=0,f=1;char c=getchar(); while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();} while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();} return x*f;}void Clean(){ n=0;topt=0;anst=0,answ=1;sum=0; memset(first,0,sizeof(first)); memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(num,0,sizeof(num)); memset(c,0,sizeof(c)); memset(p,0,sizeof(p)); memset(f,0,sizeof(f));}void add(LL x,LL y){ topt++; e[topt].to=y; e[topt].next=first[x]; first[x]=topt;}LL get(LL x){ if(x&1)return x+1; else return x-1;}void tarjan(LL now,LL from){ LL s=0; dfn[now]=low[now]=++tot; for(LL i=first[now];i;i=e[i].next) { if(get(i)==from)continue; LL to=e[i].to; if(!dfn[to]) { tarjan(to,i);s++; low[now]=min(low[now],low[to]); if(low[to]>=dfn[now])c[now]++; } else low[now]=min(low[now],dfn[to]); } if(from==0)c[now]=s-1;}LL C(LL m,LL n){ LL ret=1; for(LL i=1;i<=n;i++) ret=ret*(m-i+1)/i; return ret;}int dfs(int x){ if(c[x]>0) { if(p[x]==1)return 0; p[x]=1;return 1; } int ret=0; f[x]=sum;num[sum]++; for(int i=first[x];i;i=e[i].next) { int to=e[i].to; if(!f[to])ret+=dfs(to); } return ret;}int main(){ freopen("bzoj_2730.in","r",stdin); freopen("bzoj_2730.out","w",stdout); LL T=0; while(1) { m=init(); if(m==0)break; Clean(); for(LL i=1;i<=m;i++) { LL x,y; x=init();y=init(); n=max(n,max(x,y)); add(x,y);add(y,x); } for(LL i=1;i<=n;i++) if(!dfn[i])tarjan(i,0); for(int i=1;i<=n;i++) { if(c[i]>0)continue; if(f[i]==0) { memset(p,0,sizeof(p)); sum++; int ha=dfs(i); if(ha>=2)continue; if(ha==1)anst++,answ=answ*num[sum]; if(ha==0) { anst++;if(num[sum]==1)continue; anst++,answ=answ*C(num[sum],2); } } } cout<<"Case "<<++T<<": "<<anst<<" "<<answ<<endl; } return 0;}
codevs 1996 矿场搭建
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。