D. Harmonious Graph ( 并查集 + 思维 )

题目链接:
在这里插入图片描述
大致题意:
给你n个点,m条边的无向图,求最少添加几条边满足要求:
节点 l 可以访问到节点 r,那么节点 l 也要能够访问 l+1,l+2…r-1,r。
例如 1可访问 4,那么又要满足可访问 2,3。
解题报告:
对于每一个连通块维护成节点最大值,我们可以从该连通块中节点最小值遍历到所维护的值,若发现不是同一连通块那么就要合并,同时更新连通块维护的最大值,当遍历完后说明小于维护值得均完成,直接更新访问起点。(较大的剪枝)

#define first f
#define second s
#define ll long long
#define mp make_pair
#define pb push_back
#define pf push_front
#define lb lower_bound
#define ub upper_bound
#include <bits/stdc++.h>
#define pii pair<string,string>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int MOD=1e9+7;
const int inf=1e9+7;
const int maxn=1e6+5;
const double eps=1e-6;
const double PI=acos(-1.0);
const double e=2.718281828459;

int f[maxn];
int getfind(int x)
{
    return x==f[x]?x:f[x]=getfind(f[x]);
}
void Merge(int x,int y)
{
    x=getfind(x);y=getfind(y);
    f[min(x,y)]=max(x,y);
}
int main()
{
    int n,m,u,v;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)f[i]=i;
    for(int i=1;i<=m;i++)scanf("%d%d",&u,&v),Merge(u,v);
    int ans=0,j=1,i=1;
    for(;i<=n;){
        int k=getfind(i);
        for(;j<=k;j++){
            if(getfind(j)!=getfind(i))Merge(j,k),k=getfind(k),ans++;
        }
        i=k+1;j=k+1;
    }
    printf("%d\n",ans);
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值