You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

84 lines
2.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
const int N = 1010, M = 20010, INF = 0x3f3f3f3f;
int n, m1, m2;
int dist[N], cnt[N];
bool st[N];
int h[N], w[M], e[M], ne[M], idx;
void add(int a, int b, int c) {
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}
bool spfa(int sz) {
// spfa要调用2次所以每次调用要清空一下st,cnt,dist
memset(st, 0, sizeof st);
memset(cnt, 0, sizeof cnt);
memset(dist, 0x3f, sizeof dist); // 最短路,初始化为正无穷
queue<int> q;
// 前sz个节点入队列
for (int i = 1; i <= sz; i++) {
dist[i] = 0;
q.push(i);
st[i] = true;
}
while (q.size()) {
int u = q.front();
q.pop();
st[u] = false;
for (int i = h[u]; ~i; i = ne[i]) {
int v = e[i];
if (dist[v] > dist[u] + w[i]) { // 最短路
dist[v] = dist[u] + w[i];
cnt[v] = cnt[u] + 1;
if (cnt[v] >= n) return true; // 判负环
if (!st[v]) {
q.push(v);
st[v] = true;
}
}
}
}
return false;
}
int main() {
scanf("%d%d%d", &n, &m1, &m2);
memset(h, -1, sizeof h);
while (m1--) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
// 表示奶牛 A 和奶牛 B 至多相隔 L 的距离。
// b-a <=c ==> b < a + c
add(a, b, c);
}
while (m2--) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
// 表示奶牛 A 和奶牛 B 至少相隔 D 的距离。
// b - a >=c => a <= b - c
add(b, a, -c);
}
// 奶牛排在队伍中的顺序和它们的编号是相同的
for (int i = 1; i < n; i++) add(i + 1, i, 0); // x_{i+1} - x_i >= 0 => x_i <= x_{i+1}
if (spfa(n))
puts("-1"); // 从n出发找一下负环,如果负环存在则无解
else {
spfa(1); // 如果从1号节点出发可以成功走到n号节点则 dist[n]就不会是INF,如果是INF就说明没有走到过 n点。表示在不等式组中不存在 x_n,x_1之间的传递关联关系即x_n可以随意
if (dist[n] == INF)
puts("-2");
else
printf("%d\n", dist[n]);
}
return 0;
}