标签:
题目链接:
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; }
标签:
原文地址:http://blog.csdn.net/lianai911/article/details/45274319