COJ 0581 4022农夫喂牛

时间:2021-03-26 20:17:38
4022农夫喂牛
难度级别:D; 运行时间限制:1000ms; 运行空间限制:51200KB; 代码长度限制:2000000B
试题描述

农夫老张养了N头牛,编号分别从1到N。现在,它们要“用餐”,按照编号顺序排成一排,在它们之间有一些牛关系比较好,希望彼此之间不超过一定距离,也有些牛关系不太好,希望彼此之间至少要隔开一定距离。此外,有的牛性格比较犟,可能出现多头挤在一起的情况。给出ML个关系好的牛的信息(AL,BL,DL),MD个关系不好的牛的信息(AD,BD,DD),表示牛AL和牛BL之间的最大距离为DL,牛AD和BD之间的最小距离为DD。在满足这些条件的排列方法中,求1号牛和N号牛之间的最大距离。如果不存在任何一种排列方法满足条件则输出-1.超过10^9的情况输出-2.

输入
第一行包括三个数N,ML和MD,接下来的ML行,每行三个数分别为AL,BL和DL,再接下来的MD行,每行三个数,分别为AD,BD和DD。各行的数两两之间用一个空格分隔。
输出
输出符合题目要求的一个数。
输入示例
4 2 1
1 3 10
2 4 20
2 3 3
输出示例
27
其他说明
数据范围:1<N<=1000,0<ML,MD<=10000,0<AL<BL<=N,0<AD<BD<=N,0<DL,DD<=1000000。
 

题解:呵呵哒差分约束。。。

ML   S[b]-S[a]<=c   
MD  S[b]-S[a]>=c   转化后  S[a]-S[b]<=-c
还有相邻的两只牛之间的距离   S[i]-s[i-1]>=0  转化后  S[i-1]-S[i]<=0
我们要求最长的排队距离就是要解出这个关系   S[N]-S[1]<=x,这里可以发现约束已经符合标准,从1指向n 就是以1为源点求1到n的最短路。
我当时还各种YY区间贪心神马的。。。
 #include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#define PAU putchar(' ')
#define ENT putchar('\n')
using namespace std;
const int maxn=+,maxm=+,inf=1e9;
struct ted{int x,y,w;ted*nxt;}adj[maxm],*fch[maxn],*ms=adj;int n;
void add(int x,int y,int w){
*ms=(ted){x,y,w,fch[x]};fch[x]=ms++;return;
}
bool inq[maxn];int d[maxn],cnt[maxn];
int spfa(){
queue<int>Q;
for(int i=;i<=n;i++)d[i]=inf;
Q.push();d[]=;cnt[]=;
while(!Q.empty()){
int x=Q.front();Q.pop();inq[x]=false;
for(ted*e=fch[x];e;e=e->nxt){
int v=e->y;
if(d[v]>d[x]+e->w){
d[v]=d[x]+e->w;
if(!inq[v]){
inq[v]=true;Q.push(v);
if(++cnt[v]>n)return -;
}
}
}
}if(d[n]==inf)return -;return d[n];
}
inline int read(){
int x=,sig=;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')sig=-;ch=getchar();}
while(isdigit(ch))x=*x+ch-'',ch=getchar();
return x*=sig;
}
inline void write(int x){
if(x==){putchar('');return;}if(x<)putchar('-'),x=-x;
int len=,buf[];while(x)buf[len++]=x%,x/=;
for(int i=len-;i>=;i--)putchar(buf[i]+'');return;
}
void init(){
int ML,MD,from,to,len;
n=read();ML=read();MD=read();
while(ML--){
from=read();to=read();len=read();add(from,to,len);
}
while(MD--){
from=read();to=read();len=read();add(to,from,-len);
}
for(int i=;i<=n;i++)add(i,i-,);
write(spfa());ENT;
return;
}
void work(){
return;
}
void print(){
return;
}
int main(){init();work();print();return ;}