题目:
分析:
这道题看起来很难,但其实只需要一个巧妙的思路就好了:
程序
t
f
[
y
]
tf[y]
tf[y]标记结点
b
b
b是否在请求中出现,
p
o
s
[
b
]
pos[b]
pos[b]记录要使
b
b
b和对应的
a
a
a断开至少要从什么位置之后断开一条边,例如
a
a
a和
b
b
b分别为
1
1
1和
4
4
4,那么
p
o
s
[
4
]
=
1
pos[4]=1
pos[4]=1表明至少要从
1
1
1编号之后选择一条边,由于
b
b
b值可能相同,因此程序有取
p
o
s
[
b
]
pos[b]
pos[b]的较大值的操作。
l
l
l记录上次断掉的边的位置,初始化为
0
0
0,对于当前的
b
b
b如果
p
o
s
[
b
]
>
=
l
pos[b]>=l
pos[b]>=l表明必须再断掉一条边才能满足
a
a
a和
b
b
b不连通,此时更新答案和
l
l
l的值
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<queue>
#include<vector>
#include<map>
#include<list>
#include<ctime>
#include<iomanip>
#include<string>
#include<bitset>
#include<deque>
#include<set>
#define LL long long
#define h happy
#define XJQ 0x7f7f7f7f
using namespace std;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<22,stdin),p1 == p2)?EOF:*p1++)
char buf[(1<<22)],*p1=buf,*p2=buf;
inline int read(){
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c == '-') f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c = getchar();}
return x * f;
}
int max(int x,int y) {return x>y?x:y;}
int tf[1000001],pos[1000001];
int main()
{
int n=read(),m=read();
for(int i=1;i<=m;i++)
{
int a=read(),b=read();
tf[b]=1;pos[b]=max(pos[b],a);
}
int ans=0,l=0;
for(int i=1;i<=n;i++)
if(tf[i]&&l<=pos[i]) l=i,ans++;
printf("%d",ans);
return 0;
}