题意:给你n个点m条边,问删除前i条边后有多少个连通分块。
思路:从后往前操作,从后往前添加i条边等于添加完m条边后删掉前m-i条边,可知刚开始没有边,所以sum[m]=n;
#include <stdio.h> #include <iostream> #include <algorithm> #include <string.h> #include <queue> #include <math.h> #define M 100010 #define LL long long using namespace std; int n,m; int father[M]; int find(int x) { if(x!=father[x]) return father[x]=find(father[x]); return x; } int sum[M]; int main() { while(~scanf("%d%d",&n,&m)) { int a[M],b[M]; for(int i=0;i<=n;i++) father[i]=i; for(int i=1;i<=m;i++) scanf("%d%d",&a[i],&b[i]); sum[m]=n; for(int i=m;i>0;i--) { if(find(a[i])!=find(b[i])) { sum[i-1]=sum[i]-1; father[find(a[i])]=find(b[i]); } else sum[i-1]=sum[i]; } for(int i=1;i<=m;i++) { printf("%d\n",sum[i]); } } return 0; }
HDU 4496 D-City (并查集),布布扣,bubuko.com
原文地址:http://blog.csdn.net/u012861385/article/details/35814353