一道思维题。
传送门:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=20482
题意:
有一张无向图。给Q次删边操作,问每次操作结束后联通块的个数。
解题思路:
这题目正着想怎么也不好想。那么就反过来思考。删边改成加边。那么就很好做了。先把不删除的边按照并查集合并。然后再倒序加边。就是答案啦。。
最近做的题越来越水了哈哈。
#include <cstdio>
#include <algorithm>
#define maxn 100000+10
#define maxm 100000+10
using namespace std;
struct Node
{
int x,y,id;
bool operator < (const Node &b) const
{
return id < b.id;
}
}es[maxm];
int fa[maxn];
int ans[maxm];
int getfa(int x)
{
if(fa[x] == x) return x;
return fa[x] =getfa(fa[x]);
}
int main()
{
int n,m,q;
while(~scanf("%d %d",&n,&m))
{
for(int i = 1;i <= n;i++) fa[i] = i;
for(int i = 1;i <= m;i++)
{
scanf("%d %d",&es[i].x,&es[i].y);
es[i].id = 0;
}
scanf("%d",&q);
for(int i = q;i >= 1;i--)
{
int id;
scanf("%d",&id);
es[id].id = i;
}
sort(es+1,es+1+m);
int tot = n;
for(int i = 1;i <= m;i++)
{
int fx = getfa(es[i].x);
int fy = getfa(es[i].y);
ans[i] = tot;
if(fx != fy)
{
tot--;
fa[fx] = fy;
}
}
for(int i = m;i > m-q;i--)
{
printf("%d ",ans[i]);
}
printf("\n");
}
return 0;
}