题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4496
题目大意:
给出一张图,按照给定的边的顺序逐个删除。问每删除一条边后图的连通块数是多少。
思路:
逆向并查集求联通块数。假设一开始的时候所有点都不连通。从给定边逆着的顺序,即从最后
一条边开始添加。如果新添加的边连通了两个连通分量,则连通块数就减一,否则不改变。将
每次加边后的连通块数存起来。最后输出出来。
AC代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
struct EdgeNode
{
int u;
int v;
}Edges[1000010];
int Father[100010],Ans[100010];
int Find(int x)
{
if(Father[x] != x)
Father[x] = Find(Father[x]);
return Father[x];
}
int main()
{
int N,M;
while(~scanf("%d%d",&N,&M))
{
for(int i = 0; i < M; ++i)
scanf("%d%d",&Edges[i].u,&Edges[i].v);
for(int i = 0; i < N; ++i)
Father[i] = i;
int j = 0;
int Num = N;
for(int i = M-1; i >= 0; --i)
{
int u = Edges[i].u;
int v = Edges[i].v;
u = Find(u);
v = Find(v);
if(u != v)
{
Father[u] = v;
Ans[j++] = Num;
Num--;
}
else
Ans[j++] = Num;
}
for(int i = j-1; i >= 0; --i)
printf("%d\n",Ans[i]);
}
return 0;
}