码迷,mamicode.com
首页 > Web开发 > 详细

【并查集】bzoj1015 [JSOI2008]星球大战starwar

时间:2014-12-24 19:55:28      阅读:168      评论:0      收藏:0      [点我收藏+]

标签:

倒着处理删点,就变成了加点,于是并查集。

#include<cstdio>
using namespace std;
#define N 400001
int fa[N],kill[N],rank[N],n,m,q;
bool hav[N];
int next[N],first[N],v[N],en,x,y,anss[N],cnt;
void AddEdge(int U,int V)
{
	v[++en]=V;
	next[en]=first[U];
	first[U]=en;
}
int find(int x)
{
	if(x==fa[x]) return x;
	fa[x]=find(fa[x]);
	return fa[x];
}
void Union(int U,int V)
{
	--cnt;
	if(rank[U]<rank[V]) fa[U]=V;
	else
	  {
	  	fa[V]=U;
	  	if(rank[U]==rank[V]) ++rank[U];
	  }
}
int main()
{
	scanf("%d%d",&n,&m); cnt=n;
	for(int i=0;i<n;++i) fa[i]=i;
	for(int i=1;i<=m;++i)
	  {
	  	scanf("%d%d",&x,&y);
	  	AddEdge(x,y);
		AddEdge(y,x);
	  }
	scanf("%d",&q);
	for(int i=1;i<=q;++i)
	  {
	  	scanf("%d",&kill[i]);
	  	hav[kill[i]]=1;
	  }
	for(int i=0;i<n;++i)
	  if(!hav[i])
	    for(int j=first[i];j;j=next[j])
		  if(!hav[v[j]])
	      {
	        int f1=find(i),f2=find(v[j]);
	        if(f1!=f2) Union(f1,f2);
	      }
	for(int i=q;i>=1;--i)
	  {
	  	anss[i]=cnt-i;
	  	for(int j=first[kill[i]];j;j=next[j]) if(!hav[v[j]])
	      {
	        int f1=find(kill[i]),f2=find(v[j]);
	        if(f1!=f2) Union(f1,f2);
	      }
	    hav[kill[i]]=0;
	  }
	anss[0]=cnt;
	for(int i=0;i<=q;++i) printf("%d\n",anss[i]);
	return 0;
}

【并查集】bzoj1015 [JSOI2008]星球大战starwar

标签:

原文地址:http://www.cnblogs.com/autsky-jadek/p/4182912.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!