【BZOJ 1015】【tyvj 3487】スターウォーズスターウォーズ
5033 ワード
転送ドア1転送ドア2は前に书いてあります:考え方がありません:比较的に简単で、テーマを调べて、ちょうどするのは难しいです.私たちは考えて、逆さまに并べて、1つの星に参加するたびに、连れることができる辺を连结することに相当します.连通ブロックの数を调べてください.注意:2つの頂点が破壊されていなければ、操作コードを调べることができません.
#include"bits/stdc++.h"
using namespace std;
int tot=1,x,y,n,m,k,ans;
struct os
{
int u,v,next;
}a[400010];
int father[400010],first[400010],q[400010],outs[400010];
bool flag[400010];
int in()
{
int t=0;
char ch=getchar();
while (ch>'9'||ch<'0') ch=getchar();
while (ch>='0'&&ch<='9') t=t*10+ch-'0',ch=getchar();
return t;
}
void add(int x,int y)
{
a[++tot].u=x;
a[tot].v=y;
a[tot].next=first[x];
first[x]=tot;
}
int find(int x)
{
if (x!=father[x]) father[x]=find(father[x]);
return father[x];
}
void unions(int x,int y)
{
if (x!=y) father[x]=y,ans--;
}
main()
{
n=in();m=in();
for (int i=1;i<=m;i++)
x=in(),y=in(),
add(x,y),add(y,x);
k=in();
ans=n;
for (int i=1;i<=k;i++)
{
q[i]=in();
ans--;
flag[q[i]]=1;
}
for (int i=1;i<=n;i++) father[i]=i;
for (int i=1;i<=n;i++)
if (!flag[i])
for (int j=first[i];j;j=a[j].next)
if (!flag[a[j].v])
unions(find(a[j].v),find(a[j].u));
for (int i=k;i>=1;i--)
{
outs[i]=ans++;
flag[q[i]]=0;
for (int j=first[q[i]];j;j=a[j].next)
if (!flag[a[j].v])
unions(find(a[j].v),find(a[j].u));
}
printf("%d
",ans);
for (int i=1;i<=k;i++)
printf("%d
",outs[i]);
}