Bzoj1731 排队布局

当排队等候喂食时,奶牛喜欢和它们的朋友站得靠近些。FJ 有 N 头奶牛,编号从 1 到 N,沿一条直线站着等候喂食。奶牛排在队伍中的顺序和它们的编号是相同的。因为奶牛相当苗条,所以可能有两头或者更多奶牛站在同一位置上。即使说,如果我们想象奶牛是站在一条数轴上的话,允许有两头或更多奶牛拥有相同的横坐标。一些奶牛相互间存有好感,它们希望两者之间的距离不超过一个给定的数 L。另一方面,一些奶牛相互间非常反感,它们希望两者间的距离不小于一个给定的数 D。
给出 ML条关于两头奶牛间有好感的描述,再给出 MD条关于两头奶牛间存有反感的描述。你的工作是:如果不存在满足要求的方案,输出 −1;如果 1 号奶牛和 N号奶牛间的距离可以任意大,输出 −2;否则,计算出在满足所有要求的情况下,1 号奶牛和 N 号奶牛间可能的最大距离。


很显然,我们对于两个要在一起的情况,相当于想这两个点之间添加一条长度相应的边,使得在没有更短路的时候可以走这条

然后对于分开的则是添加一条负权边

典型的差分约束

特别的,相邻的两个牛之间之间添加一条距离为0的边

下面给出代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cmath>
using namespace std;
inline int rd(){
    int x=0,f=1;
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
    for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
    return x*f;
}
inline void write(int x){
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
    return ;
}
int n,m1,m2;
int head[100006],nxt[100006],to[100006];
int v[100006];
int total=0;
void add(int x,int y,int z){
    total++;
    to[total]=y;
    v[total]=z;
    nxt[total]=head[x];
    head[x]=total;
    return ;
}
int q[100006];
int l=0,r=0;
int book[100006];
int dis[100006];
int cnt[100006];
int f=0;
void spfa(){
    memset(dis,127,sizeof(dis));
    dis[1]=0;
    book[1]=1;
    q[++r]=1;
    while(l<r){
        int x=q[++l];
        book[x]=0;
        for(int e=head[x];e;e=nxt[e]){
            if(dis[to[e]]>dis[x]+v[e]){
                dis[to[e]]=dis[x]+v[e];
                cnt[x]++;
                if(cnt[x]==n){
                    f=1;
                    return ;
                }
                if(!book[to[e]]){
                    book[to[e]]=1;
                    q[++r]=to[e];
                }
            }
        }
    }
    return ;
}
int main(){
    n=rd(),m1=rd(),m2=rd();
    for(int i=1;i<=m1;i++){
        int x=rd(),y=rd(),z=rd();
        add(x,y,z);
    }
    for(int i=1;i<=m2;i++){
        int x=rd(),y=rd(),z=rd();
        add(y,x,-z);
    }
    for(int i=2;i<=n;i++) add(i,i-1,0);
    spfa();
    if(f) printf("-1");
    else if(dis[n]==2139062143) printf("-2");
    else write(dis[n]);
    return 0;
}

 

posted @ 2018-10-27 15:31  Bruce--Wang  阅读(197)  评论(0编辑  收藏  举报