P3084 [USACO13OPEN]照片Photo 差分约束

  

农夫约翰决定给站在一条线上的N(1 <= N <= 200,000)头奶牛制作一张全家福照片,N头奶牛编号1到N。

于是约翰拍摄了M(1 <= M <= 100,000)张照片,每张照片都覆盖了连续一段奶牛:第i张照片中包含了编号a_i 到 b_i的奶牛。但是这些照片不一定把每一只奶牛都拍了进去。

在拍完照片后,约翰发现了一个有趣的事情:每张照片中都有且仅有一只身上带有斑点的奶牛。约翰意识到他的牛群中有一些斑点奶牛,但他从来没有统计过它们的数量。 根据照片,请你帮约翰估算在他的牛群中最多可能有多少只斑点奶牛。如果无解,输出“-1”。

很容易想到差分约束  而且边也很好建   唯一要考虑的是spfa  果然又被卡了

采用双端队列优化   且遍历了一定的值以后直接退出即可

#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define pb push_back
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define inf 0x3f3f3f3
const int N=200000+5;
const int M=10*N;
int n,k;
int pos,head[M],tot;
struct Edge
{
    int nex,to,v;
}edge[M];
void add(int a,int b,int c)
{
    edge[++pos].nex=head[a];
    head[a]=pos;
    edge[pos].to=b;
    edge[pos].v=c;
}
int dis[N];
int vis[N];
int cnt[N];

int spfa()
{
    deque<int>q;
    rep(i,1,n)dis[i]=inf;
    dis[0]=0;
    vis[0]=1;
    q.push_back(0);
    while(!q.empty())
    {
        int x=q.front();
        q.pop_front();
        vis[x]=0;
        for(int i=head[x];i;i=edge[i].nex)
        {
            int v=edge[i].to,w=edge[i].v;
            if(dis[v]>dis[x]+w)
            {
                dis[v]=dis[x]+w;
                if(!vis[v])
                {
                    if(++tot>800000)return 0;
                    vis[v]=1;
                    if(q.size()&&dis[v]>dis[q.front()])q.push_back(v);
                    else q.push_front(v);
                }
            }
        }
    }
    return dis[n];
}

int main()
{
    cin>>n>>k;

    rep(i,1,k)
    {
        int a,b;cin>>a>>b;
        add(a-1,b,1);add(b,a-1,-1);
    }
    rep(i,1,n)add(i-1,i,1),add(i,i-1,0);

    if(spfa())
        cout<<dis[n];
    else cout<<"-1";

    return 0;
}
View Code

一般这种求最多的 要用最短路   (也就是  <=  式子 )

求最少的  用最长路

猜你喜欢

转载自www.cnblogs.com/bxd123/p/11394796.html