首页 > 代码库 > 【并查集】bzoj1015 [JSOI2008]星球大战starwar
【并查集】bzoj1015 [JSOI2008]星球大战starwar
倒着处理删点,就变成了加点,于是并查集。
#include<cstdio>using namespace std;#define N 400001int 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
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。