题目链接
题目:当排队等候喂食时,奶牛喜欢和它们的朋友站得靠近些。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号奶牛间可能的最大距离。
!!! 简述一下差分约束:用于求解如, a - b <= c,这样有多个不等式,最后求两个参数的最大差值。
如: a - b <= c, b - d <= c 这个不等式组, 求 a,d之前的最大差值,即 2c ...
!!! 还有一点需要注意的,此类题目 往往可能会有环,记得用SPFA判环
形如 a - b <= c 这样的不等式,可转化为一条a 到 b,权值为 c 的有向边。(不是这样的不等式,转化一下即可),有 a[1] - a[x] 的最大差值就是 1 到 x 的最短路
AC代码:
#include<cstdio>
#include<cstring>
#include<queue>
#define debug(x) cout << "[" << #x <<": " << (x) <<"]"<< endl
#define pii pair<int,int>
#define clr(a,b) memset((a),b,sizeof(a))
#define rep(i,a,b) for(int i = a;i < b;i ++)
#define pb push_back
#define MP make_pair
#define LL long long
#define INT(t) int t; scanf("%d",&t)
#define LLI(t) LL t; scanf("%I64d",&t)
using namespace std;
const int maxn = 1e3 + 10;
const int inf = 0x3f3f3f3f;
int head[maxn];
int cnt = 0;
struct xx{
int v,nex,w;
xx(){}
xx(int v,int nex,int w):
v(v),nex(nex),w(w){}
}edge[maxn * 100];
int dis[maxn];
int coun[maxn];
int vis[maxn];
int N,ML,MD;
void init(){
for(int i = 0;i < maxn;i ++){
head[i] = -1;
dis[i] = inf;
coun[i] = vis[i] = 0;
}
cnt = 0;
}
bool spfa(int x){
dis[x] = 0;
queue<int>Q;
vis[x] = 1;
Q.push(x);
while(!Q.empty()){
int now = Q.front();
Q.pop(); vis[now] = 0;
for(int i = head[now]; ~i;i = edge[i].nex){
int v = edge[i].v;
int w = edge[i].w;
if(dis[v] > dis[now] + w){
dis[v] = dis[now] + w;
if(!vis[v]){
++ coun[v];
vis[v] = 1;
if(coun[v] >= N)
return 1;
Q.push(v);
}
}
}
}
return 0;
}
int main()
{
while(~scanf("%d%d%d",&N,&ML,&MD)){
init();
for(int i = 1;i <= ML;i ++){
int a,b,c; scanf("%d%d%d",&a,&b,&c);
edge[cnt] = xx(b,head[a],c);
head[a] = cnt ++;
}
for(int i = 1;i <= MD;i ++){
int a,b,c; scanf("%d%d%d",&a,&b,&c);
edge[cnt] = xx(a,head[b],-c);
head[b] = cnt ++;
}
if(spfa(1)){
printf("-1\n");
continue;
}
if(dis[N] == inf) printf("-2\n");
else printf("%d\n",dis[N]);
}
return 0;
}