https://vjudge.net/problem/CodeForces-1253Dios
一個無向圖,對於任意l,r,若是l到r有路徑,那麼l到m也有路徑(l<m<r),問最少加多少條邊,使得上述條件成立。c++
先用並查集縮成若干個連通塊,順帶把每一個連通塊的最大值求出來,而後咱們從1到n開始遍歷每一個點,記錄當前點所在連通塊的最大值,而後若是i小於最大值並且和i-1不在一個連通塊內,就合併這兩個連通塊。計算須要合併的次數便可。spa
#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; }