关于差分约束,我强推这位大佬的博客。https://blog.csdn.net/consciousman/article/details/53812818
题目是有的牛互相之间最多只能有一个距离,有的牛最少要达到一个距离。
很容易写出不等式,由于是要求最大值,所以是要化为小于等于号,求最短路。
F[i]:表示i只牛在哪个位置
0=< F[B] - F[A] <= D
F[B] - F[A] >= D;
等价于
F[A]- F[B]<= 0;
F[B] - F[A] <= D;
F[A] - F[B] <= -D;
也就是
- b连a权值是0
- a连b权值是d
- b连a权值是-d
然后直接套上去就可以了。判断是否成立就是看有没有一个点进栈n次,进n次就是有环输出-1,如果是f【n】的值是最大值那么说明任意距离都可以输出-2;
下面是代码
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<map>
#include<vector>
using namespace std;
const int max_ = 1e7 + 7;
int n, head[max_], xiann = 1, ml,md;
inline int read()
{
int s = 0, f = 1;
char ch = getchar();
while (ch<'0' || ch>'9') {
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0'&&ch <= '9') {
s = s * 10 + ch - '0';
ch = getchar();
}
return s * f;
}
struct k {
int next, to, value;
}xian[max_];
inline void add_(int a, int b, int c) {
xian[xiann].next = head[a];
xian[xiann].to = b;
xian[xiann].value = c;
head[a] = xiann;
xiann++;
}
int vis[max_], pan[max_], f[max_];
void spfa(int now) {
queue<int> node;
node.push(now);
vis[now] = 1;
while (!node.empty()) {
int tou = node.front(); node.pop();
vis[tou] = 0;
for (int i = head[tou]; i; i = xian[i].next) {
if (f[tou] + xian[i].value < f[xian[i].to]) {
f[xian[i].to] = f[tou] + xian[i].value;
if (vis[xian[i].to] == 0) {
node.push(xian[i].to);
vis[xian[i].to] = 1;
pan[xian[i].to]++;
if (pan[xian[i].to] >= n) {
cout << "-1"; exit(0);
}
}
}
}
}
}
int main() {
n = read(), ml = read(), md = read();
while (ml--) {
int a = read(), b = read(), d = read();
add_(b, a, 0);
add_(a, b, d);
}
while (md--) {
int a = read(), b = read(), d = read();
add_(b, a, -d);
}
for (int i = 2; i <= n; i++) {
f[i] = max_;
}
spfa(1);
if (f[n] == max_) {
cout << "-2";
}
else {
cout << f[n];
}
return 0;
}