题意
https://vjudge.net/problem/CodeForces-1253D
一个无向图,对于任意l,r,如果l到r有路径,那么l到m也有路径(l<m<r),问最少加多少条边,使得上述条件成立。
思路
先用并查集缩成若干个连通块,顺带把每个连通块的最大值求出来,然后我们从1到n开始遍历每个点,记录当前点所在连通块的最大值,然后如果i小于最大值而且和i-1不在一个连通块内,就合并这两个连通块。计算需要合并的次数即可。
代码
#include<bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f #define ll long long const int N=200005; const int mod=1e9+7; const double eps=1e-8; const double PI = acos(-1.0); #define lowbit(x) (x&(-x)) int pre[N],mx[N]; int find(int x) { if(x==pre[x]) return x; return pre[x]=find(pre[x]); } int main() { std::ios::sync_with_stdio(false); int n,m; cin>>n>>m; map<int,int> mp; for(int i=1;i<=n;i++) pre[i]=mx[i]=i; for(int i=1;i<=m;i++) { int u,v; cin>>u>>v; int fu=find(u),fv=find(v); if(fu!=fv) pre[fv]=fu,mx[fu]=max(mx[fu],mx[fv]); } int mxx=0,ans=0; for(int i=1;i<=n;i++) { int f=find(i); if(i<=mxx&&find(i)!=find(i-1)) { pre[find(i-1)]=find(i); ans++; } mxx=max(mxx,mx[find(i)]); } cout<<ans<<endl; return 0; }
原文地址:https://www.cnblogs.com/mcq1999/p/11967231.html
时间: 2024-10-10 14:39:17