Harmonious Graph(并查集)

Problem - 1253D - Codeforces

你会得到一个有n个节点和m条边的无向图。节点的编号从1到n。

当且仅当以下属性成立时,该图被认为是和谐的。

对于每一个整数(l,m,r)的三重,使1≤l<m<r≤n,如果存在一条从节点l到节点r的路径,那么就存在一条从节点l到节点m的路径。
换句话说,在一个和谐图中,如果从一个节点l可以通过边(l<r)到达一个节点r,那么我们也应该能够到达节点(l+1),(l+2),...,(r-1)。

我们需要增加多少条边才能使图形和谐?

输入
第一行包含两个整数n和m(3≤n≤200 000和1≤m≤200 000)。

接下来的m行中的第i行包含两个整数ui和vi(1≤ui,vi≤n, ui≠vi),这意味着节点u和v之间有一条边。

保证给定的图是简单的(没有自循环,每对节点之间最多只有一条边)。

输出
打印我们必须添加到图中的最小数量的边,以使其和谐。

例子
inputCopy
14 8
1 2
2 7
3 4
6 3
5 7
3 8
6 8
11 12
输出拷贝
1
输入拷贝
200000 3
7 9
9 8
4 5
输出拷贝
0
注意
在第一个例子中,给定的图是不和谐的(例如,1<6<7,节点1可以通过路径1→2→7到达节点7,但节点1不能到达节点6)。然而,添加边(2,4)就足以使其和谐。

在第二个例子中,给定的图已经是和谐的。

让小的点的父节点为大的

遍历1~n找i的父节x;在i~x中若有父节点y大于x则,交换x与y的值,f[y] = x,同时变成i~x(y);

#include<iostream>
using namespace std;
int f[200050];
int find(int x)
{
	if(f[x]==x)
	return x;
	else
	return f[x]=find(f[x]);
}
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i = 1 ;i <= n;i ++)
	{
		f[i] = i; 
	}
	for(int i = 1 ;i <= m;i ++)
	{
		int l,r;
		scanf("%d %d",&l,&r);
		int x = find(l);
		int y = find(r);
		if( x < y)
		swap(x,y);
		f[y] = x;		
	}
	int ans = 0;
	for(int i = 1 ;i <= n;i++)
	{
		int x=find(i);
		while(i < x)
		{
			int y = find(i);
			if(y != x)
			{
				if(x < y)
				swap(x,y);
				f[y] = x;
				ans++;
			}
			i++;
		}
	}
	printf("%d",ans);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值