あなたはn個のノードと、m個のエッジを持つ無向グラフが与えられています。ノードは1からnまで番号が付けられています。
:グラフはなら調和と考えられ、以下の性質が成り立つ場合にのみれる
ノードrにノードLから行く経路が存在する場合、そのような1≤l<M <r≤nこと整数(L、M、R)のすべてのトリプルについて、ノードmにノードLから行く経路が存在します。
(換言すれば、調和のとれたグラフにおいて、ノードLから、我々はエッジ(L <R)を介してノードrに到達することができれば、我々は(L + 2)、ノード(L + 1)に到達することができるべきであり、...、 R-1)あまりにも。
我々はグラフが調和のとれ作るために追加する必要があるエッジの最小数は何ですか?
入力は、
最初の行は二つの整数nとm(3≤n≤200000と1≤m≤200000)を含みます。
次のm行のi番目のは、UIおよびVI(1≤ui、vi≤n、UI≠VI)、ノードuとvの間にエッジがあると、平均ことがある。二つの整数含ま
与えられたグラフが単純であることが保証されます(非自己ループは存在しない、およびノードの各ペアの間に多くても1つのエッジです)。
出力は、
我々はそれが調和のとれ作るために、グラフに追加する必要があり、エッジの最小数を印刷します。
例としては、
inputCopy
14 8
1 2
2 7
3 4
6 3
5 7
3 8
6 8
11 12
outputCopy
1
inputCopy
200000 3
7 9
9 8
4 5
outputCopy
0
注
最初の例では、与えられたグラフは調和しない(例えば、1 <6 <7、ノード1は、経路1→2→7を介してノード7に到達することができるが、ノード1はノード6に到達することができません)。しかし、エッジ(2,4)を追加することは、調和するのに十分です。
第2の例では、与えられたグラフはすでに調和あります。
//package Main;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Scanner;
public class Main {
static int maxn = 1000010;
static int[] mi = new int[maxn];
static int[] mx = new int[maxn];
static int[] pre = new int[maxn];
static class Point implements Comparable<Point>{
int mi,mx;
public Point(){}
public Point(int mi,int mx){
this.mi=mi;
this.mx=mx;
}
public int compareTo(Point a){
if(this.mi-a.mi!=0) return this.mi-a.mi;
return this.mx-a.mx;
}
};
static Point[] p = new Point[maxn];
public static int find(int x) {
if(pre[x]==x) return x;
return pre[x]=find(pre[x]);
}
public static void unite(int a,int b){
int fx=find(a);
int fy=find(b);
if(fx!=fy) pre[fx]=fy;
}
public static void main(String[] args) {
@SuppressWarnings("resource")
Scanner input = new Scanner(System.in);
int n = input.nextInt();
int m = input.nextInt();
for(int i=1;i<=n;i++){
pre[i]=i;
mi[i]=n+1;
p[i]=new Point();
}
for(int i=1;i<=m;i++){
int a=input.nextInt();
int b=input.nextInt();
unite(a,b);
}
for(int i=1;i<=n;i++){
int fi=find(i);
mi[fi]=Math.min(mi[fi],i);
mx[fi]=Math.max(mx[fi],i);
}
int cnt=0;
for(int i=1;i<=n;i++){
if(pre[i]==i){
cnt++;
p[cnt].mi=mi[i];
p[cnt].mx=mx[i];
}
}
Arrays.sort(p,1,cnt+1);
int fi=p[1].mi,fx=p[1].mx,ans=0;
for(int i=2;i<=cnt;i++){
if(p[i].mi<fx){
ans++;
fx=Math.max(fx,p[i].mx);
}
else{
fi=p[i].mi;
fx=p[i].mx;
}
}
System.out.println(ans);
}
}