Description
Farmer John决定为他的N头排列好的奶牛(1 <= N<= 200,000)做一张全景合照。这N头奶牛分别以1…N进行编号。他一共拍了M(1<= M <=100,000)张相片,每张相片都只包含有一部分位置连续的奶牛:第i张照片涵盖着编号从a_i到b_i的所有奶牛。当然,这些照片合起来并不保证包含所有的牛。
Farmer John拍摄完所有的相片后,注意到一个很有趣的现象:他拍的每张照片中有且仅有一只奶牛身上有斑点。 FJ知道他的奶牛中有一部分是身上有斑点的,但他从来没有数过这种奶牛的数目。请根据FJ的这些照片,确定可能出现的斑点牛的最大的数目;若从FJ的照片中无法推测斑点牛的数目,则输出-1。
Input
第1行:包含两个整数N、M。
第2… M+1… i +1行:每行包含两个整数a_i和b_i。
Output
输出仅一行,要求输出FJ根据他的照片所能推测出的斑点牛的最大数目;若无法推测这些奶牛的数目,则输出-1。
Sample Input
5 3
1 4
2 5
3 4
Sample Output
1
Data Constraint
1 <= N<= 200,000
.
.
.
.
.
分析
每个区间最少只有一头斑点牛,也最多只有一头斑点牛
那么一只奶牛要不就是斑点牛,要不就是正常牛,那么就是0<=sum[i]-sum[i-1]<=1
转移一下sum[R]-sum[L-1]<=1,sum[L-1]-sum[R]<=-1
那么就可以差分约束,把i和i-1之间连一条0边,i-1和i之间连一条1边,a-1和b之间连一条1边,b和a-1之间连一条-1边
.
.
.
.
.
.
程序:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
struct edge
{
int to,from,v;
}e[800010];
int n,m,vis[400010],dis[400010],head[400010],cnt=1,tot;
void insert(int x,int y,int v)
{
e[++cnt].to=y;e[cnt].from=head[x];e[cnt].v=v;head[x]=cnt;
}
int spfa()
{
deque<int> q;
for (int i=1;i<=n;i++)
dis[i]=2147483647;
vis[0]=1;
q.push_back(0);
while (q.size())
{
int u=q.front();
q.pop_front();
vis[u]=0;
for (int i=head[u];i;i=e[i].from)
if (dis[e[i].to]>dis[u]+e[i].v)
{
dis[e[i].to]=dis[u]+e[i].v;
if (!vis[e[i].to])
{
tot++;
if (tot>1926817) return -1;
vis[e[i].to]=1;
if (q.size()&&dis[e[i].to]>dis[q.front()]) q.push_back(e[i].to); else q.push_front(e[i].to);
}
}
}
return dis[n];
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++)
{
int l,r;
scanf("%d%d",&l,&r);
insert(l-1,r,1);
insert(r,l-1,-1);
}
for (int i=1;i<=n;i++)
{
insert(i-1,i,1);
insert(i,i-1,0);
}
printf("%d",spfa());
return 0;
}