原题链接:https://www.acwing.com/problem/content/1172/
需要满足三个差分约束条件:
假设左边的点是a,右边的点是b.
一些奶牛相互间存有好感,它们
希望两者之间的距离不超过一个给定的数 L。
b - a <= L;
一些奶牛相互间非常反感,它们希望两者间
的距离不小于一个给定的数 D。
b - a >= D;
还有一个条件b >= a
1 每头奶牛按编号排序 i+1 → i w = 0
<=> x[i] ≤ x[i+1]
2 两者之间的距离不超过一个给定的数L
x[b]-x[a] ≤ L a → b w = L
x[b] ≤ x[a] + L
3 两者之间的距离不小于一个给定的数D
x[b]-x[a] ≥ D
x[a] ≤ x[b]-D b → a w = -D
给的条件有限,所以只能求这些点之间的相对关系,所以题中也就
只问了我们相对关系。
问题1:
因为没有一个点可以无条件到所有点,
所以建超级源点0 从0向
假定所有x[i] ≤ x[0] + 0 从而可以从0向x[i]连一条长度为0的边
为什么需要建立超级源点:建立超级原点是为了判断
是否有负环,这样可以以所有点为起点跑一遍spfa,如果
不建立超级远点那就得跑n次spfa()
1 如果没有负环-有解
2 如果有负环-无解
问题2:
直接把所有点i加入队列 == 创建超级源点0
点1和点n距离是否可以无限大?
则可以把点1固定在一个位置上(选0位置)x[1] = 0,判断x[n]是否可以无限大
/*
需要满足三个差分约束条件:
假设左边的点是a,右边的点是b.
一些奶牛相互间存有好感,它们
希望两者之间的距离不超过一个给定的数 L。
b - a <= L;
一些奶牛相互间非常反感,它们希望两者间
的距离不小于一个给定的数 D。
b - a >= D;
还有一个条件b >= a
1 每头奶牛按编号排序 i+1 → i w = 0
<=> x[i] ≤ x[i+1]
2 两者之间的距离不超过一个给定的数L
x[b]-x[a] ≤ L a → b w = L
x[b] ≤ x[a] + L
3 两者之间的距离不小于一个给定的数D
x[b]-x[a] ≥ D
x[a] ≤ x[b]-D b → a w = -D
给的条件有限,所以只能求这些点之间的相对关系,所以题中也就
只问了我们相对关系。
问题1:
因为没有一个点可以无条件到所有点,
所以建超级源点0 从0向
假定所有x[i] ≤ x[0] + 0 从而可以从0向x[i]连一条长度为0的边
为什么需要建立超级源点:建立超级原点是为了判断
是否有负环,这样可以以所有点为起点跑一遍spfa,如果
不建立超级远点那就得跑n次spfa()
1 如果没有负环-有解
2 如果有负环-无解
问题2:
直接把所有点i加入队列 == 创建超级源点0
点1和点n距离是否可以无限大?
则可以把点1固定在一个位置上(选0位置)x[1] = 0,判断x[n]是否可以无限大
*/
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1010, M = 10000 + 10000 + 1000 + 10, INF = 0x3f3f3f3f;
int n, m1, m2;
int h[N], e[M], w[M], ne[M], idx;
int dist[N];
int q[N], cnt[N];
bool st[N];
void add(int a, int b, int c)
{
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++ ;
}
bool spfa(int size)
{
// 每次做spfa记得清空数组
int hh = 0, tt = 0;
memset(dist, 0x3f, sizeof dist);
memset(st, 0, sizeof st);
memset(cnt, 0, sizeof cnt);
// 用超级源点的时候,把所有的点dist设为0,然后加到队列中
// 不用超级源点的时候,只需要加1号点就行,求1到n的最长路。
for (int i = 1; i <= size; i ++ )
{
q[tt ++ ] = i;
dist[i] = 0;
st[i] = true;
}
while (hh != tt)
{
int t = q[hh ++ ];
if (hh == N) hh = 0;
st[t] = false;
for (int i = h[t]; ~i; i = ne[i])
{
int j = e[i];
if (dist[j] > dist[t] + w[i])
{
dist[j] = dist[t] + w[i];
cnt[j] = cnt[t] + 1;
if (cnt[j] >= n) return true;
if (!st[j])
{
q[tt ++ ] = j;
if (tt == N) tt = 0;
st[j] = true;
}
}
}
}
return false;
}
int main()
{
scanf("%d%d%d", &n, &m1, &m2);
memset(h, -1, sizeof h);
for (int i = 1; i < n; i ++ ) add(i + 1, i, 0);
while (m1 -- )
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
if (a > b) swap(a, b);
add(a, b, c);
}
while (m2 -- )
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
if (a > b) swap(a, b);
add(b, a, -c);
}
if (spfa(n)) puts("-1");
else
{
spfa(1);
if (dist[n] == INF) puts("-2");
else printf("%d\n", dist[n]);
}
return 0;
}