[HNOI2012]矿场搭建,洛谷之提高历练地,强连通分量

正题

      [HNOI2012]矿场搭建

      点双连通分量??边双连通分量??

      不懂??

     其实这题也没那么麻烦,代码也没那么长~

     我们先找割点,然后分类讨论一下。

     我们dfs找出与当前节点(枚举)在同一连通块的点,如果是割点就不用往下搜了,那么我们求出来的就是,割点被炸掉之后的连通分块。

     当 当前连通分块的割点有两个及以上时,那么无论炸掉那个点,该连通分块的点都可以通过另一割点去到另一连通分块。

     当 当前连通分块的割点有一个时,那么如果炸掉的是割点,该连通分块的点出不去了,就在这个连通分块建一个出口。

     当 当前连通分块没有割点,那么我们就要建两个出口,这样就可以使得无论炸掉那个点,另外的节点都有出口。

      方案算一下即可,当然不能出口不能设在割点。

扫描二维码关注公众号,回复: 182839 查看本文章
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<stack>
using namespace std;

int m;
int n;
struct edge{
	int x,y,next;
}s[10010];
struct node{
	int dfn,low;
}op[10010];
int first[10010];
int len=0;
int now=0;
bool cut[10010];
long long ans1,ans2=1;
int vis[10010];
int T;
int num=0;
long long cnt=0;
int nn=0;

void ins(int x,int y){
	len++;
	s[len].x=x;s[len].y=y;s[len].next=first[x];first[x]=len;
}

void Tarjan(int x,int fa){
	op[x].dfn=op[x].low=++now;
	int son=0;
	for(int i=first[x];i!=0;i=s[i].next){
		int y=s[i].y;
		if(op[y].dfn==0){
			Tarjan(y,x);
			if(op[x].dfn<=op[y].low) {//找割点
				cut[x]=1;
				son++;
			}
			if(op[y].low<op[x].low) op[x].low=op[y].low;
		}
		else if(op[y].dfn<op[x].low) op[x].low=op[y].dfn;
	}
	if(fa==0 && son<2) cut[x]=0;
}

void dfs(int x){
	vis[x]=T;cnt++;
	for(int i=first[x];i!=0;i=s[i].next){
		int y=s[i].y;
		if(vis[y]!=T && cut[y]) num++,vis[y]=T;//如果是割点,不用往下搜。
		if(!vis[y] && !cut[y]) dfs(y);//如果不是割点,继续往下搜。
	}
}

int main(){
	while(1){
		nn++;T=0;len=0;now=0;
		ans1=0,ans2=1;
		memset(op,0,sizeof(op));
		memset(first,0,sizeof(first));
		memset(cut,false,sizeof(cut));
		memset(vis,0,sizeof(vis));
		scanf("%d",&m);
		if(m==0) break;
		n=0;
		for(int i=1;i<=m;i++){
			int x,y;
			scanf("%d %d",&x,&y);
			ins(x,y);ins(y,x);
			n=max(n,max(x,y));
		}
		for(int i=1;i<=n;i++)
			if(op[i].dfn==0) Tarjan(i,0);
		for(int i=1;i<=n;i++){
			if(!vis[i] && !cut[i]){
				num=0,cnt=0;T++;//num记录的是当前连通分块中的割点数量,cnt是当前连通分块其他点的点数
				dfs(i);
				if(num==0) ans1+=2,ans2*=cnt*(cnt-1)/2;//组合数计算
				if(num==1) ans1+=1,ans2*=cnt;
			}
		}
		printf("Case %d: %lld %lld\n",nn,ans1,ans2);
	}
}

猜你喜欢

转载自blog.csdn.net/deep_kevin/article/details/80039119
今日推荐