并查集
正序处理时间复杂度为n^2,考虑逆序处理,这样,时间复杂度从n^2降为nlogn
附上代码:
#include <cstdio>#include <algorithm>#include <cmath>#include <cstring>#include <cstdlib>#include <iostream>#include <queue>using namespace std;#define N 400005int fa[N<<1],n,m,K,head[N<<1],cnt,q[N],ans[N];struct node{int to,next;}e[N<<1];void add(int x,int y){e[cnt].to=y;e[cnt].next=head[x];head[x]=cnt++;return ;}int find(int x){int p=x,t;while(fa[p]!=p)p=fa[p];while(x!=p)t=fa[x],fa[x]=p,x=t;return p;}bool vis[N];int main(){for(int i=1;i<N;i++)fa[i]=i;memset(head,-1,sizeof(head));memset(vis,1,sizeof(vis));scanf("%d%d",&n,&m);for(int i=1;i<=m;i++){int x,y;scanf("%d%d",&x,&y);x++,y++;add(x,y);add(y,x);}scanf("%d",&K);ans[K]=n-K;for(int i=1;i<=K;i++){scanf("%d",&q[i]);q[i]++;vis[q[i]]=0;}for(int i=1;i<=n;i++){if(!vis[i])continue;for(int j=head[i];j!=-1;j=e[j].next){int to1=e[j].to;if(!vis[to1])continue;int fx=find(i),fy=find(to1);if(fx!=fy){fa[fx]=fy;ans[K]--;}}}vis[q[K]]=1;for(int i=K-1;i>=0;i--){ans[i]=ans[i+1]+1;for(int j=head[q[i+1]];j!=-1;j=e[j].next){int to1=e[j].to;if(!vis[to1])continue;int fx=find(q[i+1]),fy=find(to1);if(fx!=fy){fa[fx]=fy;ans[i]--;}}vis[q[i]]=1;}for(int i=0;i<=K;i++){printf("%d\n",ans[i]);}return 0;}
[JSOI2008]星球大战starwar BZOJ1015
原文地址:https://www.cnblogs.com/Winniechen/p/9005135.html