【链接】
http://poj.org/problem?id=3169
【题意】
有N个点,其中有ml个限制条件:点a,点b,的最长距离为d,有md个限制条件,点a,点b,的最短距离为d;点按序号顺序排,求第一个点到最后一个点的最长距离。
【思路】
记录第i号牛的位置d[i],首先,牛是按标号排序的,有d[i]<=d[i+1].
对于关系好的牛之间的最大距离,有d[AL]+DL<=d[BL].同样有:d[AD]+DD<=d[BD].
问题转化为,在满足三类不等式条件下的d[N]-d[1]的最大值
不等式特点:所有式子两边都只出现了一个变量。
最短路问题中:记从点s出发,到各个顶点v的最短路的距离为d[v].因此,对于每条权值为w的边e=(v,u),都有d(v)+w>=d(u).
反之,对于每条满足不等式的d中,d(v)-d(s)的最大值就是从s-v的最距离。
【代码】
#include<cstdio>
#include<math.h>
#include<string>
#include<vector>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn = 1e5 + 6;
const int inf = 0x3f3f3f3f;
int d[maxn];
struct node1 {
int a,b,c;
}k1[maxn];
struct node2 {
int a, b, c;
}k2[maxn];
int main() {
//freopen("binary.in", "r", stdin);
//freopen("binary.out", "w", stdout);
memset(d, inf, sizeof(d));
d[0] = 0;
int n, ml, md;
scanf("%d%d%d", &n, &ml, &md);
//A B D:B-A>=D
for (int i = 0; i < ml; i++) {
int a, b, d;
scanf("%d%d%d", &k1[i].a, &k1[i].b, &k1[i].c);
}
//A B D:B-A<=D
for (int i = 0; i < md; i++) {
int a, b, d;
scanf("%d%d%d", &k2[i].a, &k2[i].b, &k2[i].c);
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if(d[j+1]<inf)d[j] = min(d[j], d[j + 1]);
}
for (int j = 0; j < ml; j++) {
if(d[k1[j].a-1]<inf)
d[k1[j].b - 1] = min(d[k1[j].b - 1], d[k1[j].a - 1] + k1[j].c);
}
for (int j = 0; j < md; j++) {
d[k2[j].a - 1] = min(d[k2[j].a - 1], d[k2[j].b - 1] - k2[j].c);
}
}
if (d[0] < 0)printf("-1\n");
else if (d[n - 1] == inf)printf("-2\n");
else printf("%d\n", d[n - 1]);
}