BZOJ2730 矿场搭建
2015-06-04 15:38
162 查看
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2730
基本思路,注意到n非常的小,所以暴力即可。
首先显然我们要找出所有的割点,$O(n^2)$并查集。
我们将所有的割点删除,然后将剩余的边用并查集维护,化为很多个联通块。
有三种情况:
1.联通块和一个割点相连,这种情况下显然只能在当前联通块里任选一个点建一个逃生点。
2.与两个割点相连,这种情况下不用建逃脱点因为他只能割掉其中一个割点。
3.没有割点,至少建两个(任选两个点),因为有可能逃生点被破坏了,所以为两个。
至于情况数,因为同一联通块的点没有不同,所以直接乘起来。
View Code
基本思路,注意到n非常的小,所以暴力即可。
首先显然我们要找出所有的割点,$O(n^2)$并查集。
我们将所有的割点删除,然后将剩余的边用并查集维护,化为很多个联通块。
有三种情况:
1.联通块和一个割点相连,这种情况下显然只能在当前联通块里任选一个点建一个逃生点。
2.与两个割点相连,这种情况下不用建逃脱点因为他只能割掉其中一个割点。
3.没有割点,至少建两个(任选两个点),因为有可能逃生点被破坏了,所以为两个。
至于情况数,因为同一联通块的点没有不同,所以直接乘起来。
#include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <set> #define N 510 #define p E[i].x #define LL long long using namespace std; struct edge{ int x,to; }E[N<<1]; int m,n,g ,totE,fa ,cnt ,siz ; set<int> G ; bool cut ; inline void addedge(int x,int y){ E[++totE]=(edge){y,g[x]}; g[x]=totE; E[++totE]=(edge){x,g[y]}; g[y]=totE; } int find(int x){ if(fa[x]!=x) fa[x]=find(fa[x]); return fa[x]; } void add(int x,int y){ int r1=find(x),r2=find(y); if(r1!=r2) fa[r2]=r1; } bool check(int x){ for(int i=1;i<=n;i++) fa[i]=i; for(int i=2;i<=totE;i+=2) if(E[i].x!=x&&E[i^1].x!=x) add(E[i].x,E[i^1].x); int tmp=0; for(int i=1;i<=n;i++){ if(i==x) continue; if(!tmp) tmp=find(i); if(find(i)!=tmp) return 1; } return 0; } int main(){ int caset=0; while(scanf("%d",&m)==1){ if(!m) break; for(int i=1;i<=n;i++){ cut[i]=0; siz[i]=g[i]=cnt[i]=0; G[i].clear(); } printf("Case %d: ",++caset); totE=1; n=0; for(int i=1,x,y;i<=m;i++){ scanf("%d%d",&x,&y); addedge(x,y); n=max(n,x); n=max(n,y); } bool fl=0; for(int i=1;i<=n;i++) if(check(i)) cut[i]=1,fl=1; if(!fl){ printf("%d %lld\n",2,((n-1)*(LL)n)/2); continue; } for(int i=1;i<=n;i++) fa[i]=i; for(int i=2;i<=totE;i+=2) if(!cut[E[i].x]&&!cut[E[i^1].x]) add(E[i].x,E[i^1].x); for(int x=1;x<=n;x++){ siz[find(x)]++; if(!cut[x]) continue; for(int i=g[x];i;i=E[i].to) if(!cut[p]) G[find(p)].insert(x); } int ans=0; LL ansv=1; for(int i=1;i<=n;i++){ if(cut[i]) continue; if(find(i)!=i) continue; if(G[i].size()<2){ ans++; ansv*=siz[i]; } } printf("%d %lld\n",ans,ansv); } }
View Code
相关文章推荐
- 如何在安装32位Oracle客户端组件的情况下以64位模式运行
- 2015年大一下第13周项目1-小玩文件
- CCNA学习指南 网络互联
- Process.StandardOutput.ReadToEnd()卡死假象(非卡死)
- Java Exlips 操作 Hadoop
- Building a Raspberry Pi 2 WebRTC camera
- 理解SQL Server中的权限体系(下)----安全对象和权限
- navicat导入mysql数据库sql时报错
- linux 下重启mysql数据库的方法
- SVN服务器客户端以及环境的搭建和使用
- 自己写的存储过程要记住二:(一个删了好多表的存储过程)
- UVa 10118 Free Candies
- 使用ssh或者远程执行命令是的一些问题解决方法
- Centos 安装Ftp客户端和开启vsftp服务
- Linux 强制位、冒险位
- Linux服务器上设置SSH登录后发送email提醒的方法
- 期权期货及其他衍生产品
- 第三天 ThinkPHP手把手快速拼接网站(三)
- 理解SQL Server中的权限体系(上)----主体
- drupal node机制理解