JZOJ 3233. 照片

题目

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

 

分析

 

  • 差分约束
  • sum[r]-sum[l-1]=1
  • sum[i]-sum[i-1]<=1
  • 所以l-1 r 1   r l-1 -1  i-1 i 1 i-1 i 0

 

代码

 1 #include<iostream>
 2 #include<queue>
 3 #include<cstdio>
 4 using namespace std;
 5 const int inf=100000000;
 6 struct sb
 7 {
 8     int to,nx,w;
 9 }g[1000001*4];
10 int cnt,list[1000001*4];
11 void add(int x,int y,int w)
12 {
13     g[++cnt].to=y; g[cnt].nx=list[x]; g[cnt].w=w; list[x]=cnt;
14 }
15 int dis[1000001],vis[1000001];
16 int n,m;
17 int tot;
18 int spfa()
19 {
20     for(int i=0;i<=n;i++) dis[i]=inf;
21     deque<int> q;
22     dis[0]=0; q.push_back(0); vis[0]=1;
23     while (!q.empty())
24     {
25         int x=q.front(); q.pop_front(); vis[x]=0;
26         for (int i=list[x];i;i=g[i].nx)
27         {
28             int y=g[i].to;
29             if (dis[x]+g[i].w<dis[y])
30             {
31                 dis[y]=dis[x]+g[i].w;
32                 if (!vis[y])
33                 {
34                     if (++tot>1926817) return -1;
35                     vis[y]=1;
36                     if (q.size()&&dis[g[i].to]>dis[q.front()]) q.push_back(g[i].to); else q.push_front(g[i].to);
37                 }
38             }
39        }
40     
41     } 
42     return dis[n];
43 } 
44 int main ()
45 {
46     scanf("%d%d",&n,&m);
47     for (int i=1,l,r;i<=m;i++)
48     {
49         scanf("%d%d",&l,&r);
50         add(l-1,r,1); add(r,l-1,-1);
51     }
52     for (int i=1;i<=n;i++)
53       add(i-1,i,1),add(i,i-1,0);
54     long long a=spfa();
55     if (a==inf||a==-1)  cout<<-1;
56     else cout<<a;
57  } 
为何要逼自己长大,去闯不该闯的荒唐
原文地址:https://www.cnblogs.com/zjzjzj/p/11172993.html