bzoj1015 [JSOI2008]星球大战starwar

题目链接

机智的倒序操作

+并查集离线处理

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<string>
 5 #include<cstring>
 6 #include<cmath>
 7 #include<algorithm>
 8 #include<ctime>
 9 #include<queue>
10 #include<stack>
11 #include<map>
12 #include<set>
13 using namespace std;
14 int ed=1,n,m,d,fa[400040],head[400040],q[400040],ans[400040];
15 int sum,bo[400040],dis[400040],next[400040],zhi[400040];
16 int find(int x)
17 {
18     return x==fa[x]?x:fa[x]=find(fa[x]);
19 }
20 inline int getint()
21 {
22     int f=1,ret=0;
23     char ch=getchar();
24     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
25     while(ch>='0'&&ch<='9')ret*=10,ret+=ch-'0',ch=getchar();
26     return f==-1?-ret:ret;
27 }
28 void add(int a,int b)
29 {
30     next[++ed]=head[a],head[a]=ed,zhi[ed]=b;
31     next[++ed]=head[b],head[b]=ed,zhi[ed]=a;
32 }
33 void hh(int x)
34 {
35     int xx=find(x),q;
36     for(int i=head[x];i;i=next[i])
37         if(bo[zhi[i]])
38         {
39             q=find(zhi[i]);
40             if(xx!=q)fa[q]=xx,sum--;
41         }
42 }
43 int main()
44 {
45     n=getint(),m=getint();
46     for(int i=0;i<n;i++)fa[i]=i;
47     for(int i=1;i<=m;i++)
48     {
49         int q,w;
50         q=getint(),w=getint();
51         add(q,w);
52     }
53     d=getint();
54     for(int i=1;i<=d;i++)
55     {
56         q[i]=getint();
57         dis[q[i]]=1;
58     }
59     for(int i=0;i<n;i++)
60         if(!dis[i])sum++,hh(i),bo[i]=1;
61     ans[d+1]=sum;
62     for(int i=d;i>=0;i--)
63         sum++,hh(q[i]),bo[q[i]]=1,ans[i]=sum;
64     for(int i=1;i<=d+1;i++)printf("%d
",ans[i]);
65     return 0;
66 }
原文地址:https://www.cnblogs.com/HugeGun/p/5151069.html