Atcoder beginner contest 120D Decayed Bridges

https://atcoder.jp/contests/abc120/tasks/abc120_d
题意:一张图的边由输入的顺序不断被切断,求每次切断后有多少对点不能互相到达。
思路:可以用并查集解决。倒着操作,往里加边。输出的答案为总的点对的数量减去每一个集合中点对的数量之和。模拟就过了。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
#define pii pair
#define mp make_pair
#define fi first
#define se second
#define inf 0x7fffffff
using namespace std;
int r[100010][2],fa[100010];
ll ans[100010],b[100010];
int find(int x)
{
	if(fa[x]==x)
	{
		return x;
	}
	return fa[x]=find(fa[x]);
}
int main()
{
	int i,j,k,n,m,x,y;
	scanf("%d%d",&n,&m);
	for(i=0;i<m;i++)
	{
		scanf("%d%d",&r[i][0],&r[i][1]);
	}
	for(i=1;i<=n;i++)
	{
		fa[i]=i;
		b[i]=1;
	}
	ll sum=1ll*n*(n-1)/2;
	for(i=m-1;i>=0;i--)
	{
		ans[i]=sum;
		x=r[i][0];
		y=r[i][1];
		find(x);
		find(y);
		if(fa[x]==fa[y])
		{
			continue;
		}
		sum-=((b[fa[x]]+b[fa[y]])*(b[fa[x]]+b[fa[y]]-1)/2-b[fa[x]]*(b[fa[x]]-1)/2-b[fa[y]]*(b[fa[y]]-1)/2);
		b[fa[y]]+=b[fa[x]];
		fa[fa[x]]=fa[y];
	}
	for(i=0;i<m;i++)
	{
		printf("%lld\n",ans[i]);
	}
	return 0;
}

你可能感兴趣的:(atcoder)