1. 程式人生 > >bzoj1015: [JSOI2008]星球大戰starwar 並查集+離線處理

bzoj1015: [JSOI2008]星球大戰starwar 並查集+離線處理

war 處理 ace clas getc jsoi2008 include blog read

題目傳送門

這道題可以改為離線處理 倒著找答案 這樣刪點就變成加點了 有了這個思想題目就很好寫了哇 23333

技術分享
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=400007;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<0||c>9){if(c==-) f=-1; c=getchar();}
    while(c>=0&&c<=
9){ans=ans*10+(c-0); c=getchar();} return ans*f; } int n,m,k,tot,sum; int fa[M],ans[M],usd[M],in[M],first[M],q[M]; struct node{int to,next;}e[2*M]; void ins(int a,int b){sum++; e[sum].to=b; e[sum].next=first[a]; first[a]=sum;} void insert(int a,int b){ins(a,b); ins(b,a);} int find(int x){return
fa[x]==x?x:fa[x]=find(fa[x]);} void add(int x){ int p=find(x); for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(usd[now]){ int q=find(now); if(p!=q){fa[q]=p; tot--;} } } } int main() { int x,y; n=read(); m=read(); for(int
i=0;i<n;i++) fa[i]=i; for(int i=1;i<=m;i++) x=read(),y=read(),insert(x,y); k=read(); for(int i=1;i<=k;i++) q[i]=read(),in[q[i]]=1; for(int i=0;i<n;i++) if(!in[i]){ tot++; add(i); usd[i]=1; } ans[k+1]=tot; for(int i=k;i;i--){ tot++; add(q[i]); usd[q[i]]=1; ans[i]=tot; } for(int i=1;i<=k+1;i++) printf("%d\n",ans[i]); return 0; }
View Code

bzoj1015: [JSOI2008]星球大戰starwar 並查集+離線處理