BZOJ 1015 并查集+离线倒序

Posted on 2016-06-07 21:25  yyjxx2010xyu  阅读(...)  评论(...编辑  收藏

统计块个数写错了调了好久啊,BZOJ1696的弱化版本。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <cstdio>
 5 #include <map>
 6 #define fi first
 7 #define se second
 8 #define mp make_pair
 9 #define pa pair<int,int>
10 using namespace std;
11 inline void Get_Int(int &x)
12 {
13     x=0;  char ch=getchar(); int f=1;
14     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
15     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} x*=f;
16 }
17 inline void Put_Int(int x)
18 {
19     char ch[20]; int top=0;
20     if (x==0) ch[++top]='0';
21     while (x) ch[++top]=x%10+'0',x/=10;
22     while (top) putchar(ch[top--]); putchar('\n');
23 }
24  
25 const int Maxn=500200;
26 int father[Maxn],head[Maxn],Ans[Maxn],res,u[Maxn],cnt,v[Maxn],n,m,Q,Pos[Maxn];
27 bool b[Maxn],ret[Maxn];
28 struct Edge{int to,next;}edge[Maxn<<1];
29 int getfather(int x) {if (x==father[x]) return x; return father[x]=getfather(father[x]);}
30 inline void Merge(int u,int v) {father[getfather(u)]=getfather(v);}
31 inline void Add(int u,int v) {edge[cnt].to=v;edge[cnt].next=head[u];head[u]=cnt++;}
32 inline void Build()
33 {
34     for (int i=1;i<=n;i++)
35     {
36         if (b[i]) continue;
37         for (int j=head[i];j!=-1;j=edge[j].next) if (!b[edge[j].to]) Merge(i,edge[j].to);
38     }
39 }
40  
41 int main()
42 {
43     Get_Int(n),Get_Int(m);
44     for (int i=1;i<=n;i++) father[i]=i;
45     memset(head,-1,sizeof(head)); cnt=0;
46     memset(b,false,sizeof(b));
47     for (int i=1;i<=m;i++) Get_Int(u[i]),Get_Int(v[i]),Add(u[i]+1,v[i]+1),Add(v[i]+1,u[i]+1);
48     Get_Int(Q);
49     for (int i=1;i<=Q;i++) Get_Int(Pos[i]),Pos[i]++,b[Pos[i]]=true;
50     Build();
51     memset(ret,false,sizeof(ret));
52     for (int i=1;i<=n;i++) ret[getfather(i)]=true;
53     int res=0; for (int i=1;i<=n;i++) if (ret[i]) res++;//写成了ret[getfather[i]]了>_<
54     res-=Q;
55     for (int i=Q;i>=1;i--)
56     {
57         Ans[i]=res;
58         b[Pos[i]]=false;
59         for (int j=head[Pos[i]];j!=-1;j=edge[j].next) 
60             if (!b[edge[j].to])
61                 if (getfather(Pos[i])!=getfather(edge[j].to)) res--,Merge(Pos[i],edge[j].to);
62         res++;
63     }
64     Ans[0]=res;
65     for (int i=0;i<=Q;i++) Put_Int(Ans[i]);
66     return 0;
67      
68 }
C++