首页 > 代码库 > BZOJ2730: [HNOI2012]矿场搭建
BZOJ2730: [HNOI2012]矿场搭建
传送门
图的连通性相关的必和割点割边之类的有关。
题目要求对于一个无向图,任意一点被删除后,所有点都和某些指定点是联通的。
这道题比较简单的做法就是求出来所有的块。对于一个块,如果块里有两个及两个以上的割点,那么这个块是不需要钦定点的。两个一下的需要分类讨论。
对于只有一个割点的,肯定要钦定一个点,不然割点挂了整个块就GG了。
对于不存在割点的,要钦定一个点和一个备胎点,免得钦定的点被炸了。
求方案数可以用乘法原理。同样,存在两个及两个以上割点的块不需要考虑,一个和不存在的需要分类讨论。
对于只有一个割点的块,可以挑选的点有$size-1$个。
对于一个割点都没有的块,可以挑选的点有$size \times (size-1)$个。
累乘起来就行了。
//BZOJ 2730//by Cydiater//2016.11.1#include <iostream>#include <cstdlib>#include <queue>#include <map>#include <ctime>#include <cmath>#include <cstring>#include <string>#include <algorithm>#include <cstdio>#include <bitset>#include <set>#include <iomanip>using namespace std;#define ll long long#define up(i,j,n) for(int i=j;i<=n;i++)#define down(i,j,n) for(int i=j;i>=n;i--)#define cmax(a,b) a=max(a,b)#define cmin(a,b) a=min(a,b)#define Auto(i,node) for(int i=LINK[node];i;i=e[i].next)const int MAXN=1e5+5;const int oo=0x3f3f3f3f;inline int read(){ char ch=getchar();int x=0,f=1; while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f;}int N,M,LINK[MAXN],len=0,dfn[MAXN],low[MAXN],dfs_clock=0,color_num=0,color[MAXN],casenum=0;bool iscut[MAXN],vis[MAXN];ll ans1,ans2,siz,cutnum;struct edge{ int y,next;}e[MAXN];namespace solution{ inline void insert(int x,int y){e[++len].next=LINK[x];LINK[x]=len;e[len].y=y;} inline void Insert(int x,int y){insert(x,y);insert(y,x);} void tarjan(int node,int father){ dfn[node]=low[node]=++dfs_clock; int child=0; Auto(i,node)if(e[i].y!=father){ if(!dfn[e[i].y]){ tarjan(e[i].y,node);child++; cmin(low[node],low[e[i].y]); if(low[e[i].y]>=dfn[node])iscut[node]=1; }else cmin(low[node],dfn[e[i].y]); } if(father==0&&child==1)iscut[node]=0; } void dfs(int node){ color[node]=color_num;if(iscut[node])return;siz++; Auto(i,node){ if(iscut[e[i].y]&&color[e[i].y]!=color_num){ cutnum++;color[e[i].y]=color_num; } if(!color[e[i].y])dfs(e[i].y); } } void slove(){ N=len=dfs_clock=0; memset(LINK,0,sizeof(LINK)); memset(iscut,0,sizeof(iscut)); up(i,1,M){int x=read(),y=read();cmax(N,max(x,y));Insert(x,y);} memset(dfn,0,sizeof(dfn)); up(i,1,N)if(!dfn[i])tarjan(i,0); memset(color,0,sizeof(color)); color_num=0;ans1=0;ans2=1; up(i,1,N)if(!iscut[i]&&!color[i]){ color_num++;siz=cutnum=0;dfs(i); if(cutnum==0){ans1+=2;ans2*=(ll)siz*(ll)(siz-1)/2;} if(cutnum==1){ans1++;ans2*=(ll)siz;} } printf("Case %d: %lld %lld\n",++casenum,ans1,ans2); }}int main(){ //freopen("input.in","r",stdin); using namespace solution; while(scanf("%d",&M)!=EOF)if(M!=0)slove(); return 0;}
BZOJ2730: [HNOI2012]矿场搭建
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。