bzoj 1731: [Usaco2005 dec]Layout 排队布局 ——差分约束

Description

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

Input

* Line 1: Three space-separated integers: N, ML, and MD.

* Lines 2..ML+1: Each line contains three space-separated positive integers: A, B, and D, with 1 <= A < B <= N.

Cows A and B must be at most D (1 <= D <= 1,000,000) apart.

* Lines ML+2..ML+MD+1: Each line contains three space-separated positive integers:

A, B, and D, with 1 <= A < B <= N. Cows A and B must be at least D (1 <= D <= 1,000,000) apart.

Output

* Line 1: A single integer. If no line-up is possible, output -1. If cows 1 and N can be arbitrarily far apart, output -2. Otherwise output the greatest possible distance between cows 1 and N.

Sample Input

4 2 1
1 3 10
2 4 20
2 3 3

INPUT DETAILS:

There are 4 cows. Cows #1 and #3 must be no more than 10 units
apart, cows #2 and #4 must be no more than 20 units apart, and cows
#2 and #3 dislike each other and must be no fewer than 3 units apart.

Sample Output

27

四只牛分别在0,7,10,27.
——————————————————————————————
这道题是裸的差分约束 属: 最大距离——最短路
记第i头牛的位置为di 因为编号小的不能大于编号大的
即di>=di-1
这个时候 i向i-1连一条权值为0的边 保证位置关系
如果i j 有好感 那么d[i]<=d[j]+L 这个时候就从j向i连一条长度为L的边
如果 i j 相互厌恶 那么d[j]<=d[i]-d 这个时候就从i向j连一条长度为-d的边
这样连边之后跑一遍最短路就可以了 
至于为什么是最短路 因为我们这样连边都是连的最大的边了
最短路最后得到的是d[n]-d[1]<=a,最长路最后得到的是d[n]-d[1]>=b
因为要求d[n]-d[1]的最大值,所以要跑最短路
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define LL long long
const int M=1e3+7,N=1e5+7,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,ml,md,h[M],vis[M];
int x,y,w,dis[M];
int first[M],cnt;
struct node{int to,next,w;}e[N];
void ins(int a,int b,int w){e[++cnt]=(node){b,first[a],w}; first[a]=cnt;}
std::queue<int>q;
bool f=false;
void spfa(){
    memset(dis,0x3f,sizeof(dis));
    q.push(1); dis[1]=0; 
    vis[1]=1; h[1]=1;
    while(!q.empty()){
        int x=q.front(); q.pop(); 
        for(int i=first[x];i;i=e[i].next){
            int now=e[i].to;
            if(dis[now]>dis[x]+e[i].w){
                dis[now]=dis[x]+e[i].w;
                if(!vis[now]){
                    vis[now]=1; q.push(now);
                    h[now]++; if(h[now]==n){f=true; return ;}
                }
            }
        }
        vis[x]=0;
    }
}
int main(){
    n=read(); ml=read(); md=read();
    for(int i=1;i<=ml;i++) x=read(),y=read(),w=read(),ins(x,y,w);
    for(int i=1;i<=md;i++) x=read(),y=read(),w=read(),ins(y,x,-w);
    for(int i=1;i<n;i++) ins(i+1,i,0);
    spfa();
    if(f) printf("-1
");
    else if(dis[n]==inf) printf("-2
");
    else printf("%d
",dis[n]);
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/lyzuikeai/p/7566817.html