Layout |
---|
题意: 有些奶牛之间关系好,距离不能超过一定距离,有些奶牛关系不好,距离不能小于一定距离。问一号奶牛和n号奶牛的可能的最大距离,如果不存在满足要求的方案,输出-1;如果1号奶牛和N号奶牛间的距离可以任意大,输出-2
题解: 直接看这篇博客学习差分约束系统,回来加亿点细节套最短路的SPFA模板就能做。
注意: 我们并不知道根据所给的约束条件,是否能够建立起一个连通的图,所以可以将所有的点和饥饿一个超级源点连接一条权值为0的边,使其成为一个连通图。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<iomanip>
#include<cstdio>
#include<string>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
inline int read() {
int s = 0, w = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-') w = -1; ch = getchar();}
while(ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
return s * w;
}
const int N = 1e3 + 10;
int n, l, d;
int cnt, head[N * 100];
int dis[N], inq[N], neg[N];
struct edge{ int to, w, next;} e[N * 100];
void addedge(int u, int v, int w) { e[cnt].to = v, e[cnt].w = w, e[cnt].next = head[u], \
head[u] = cnt++;}
void init() {cnt = 0; for(int i = 0; i < N; i++) { neg[i] = inq[i] = 0, dis[i] = inf, \
head[i] = -1;}}
int spfa() {
queue<int> Q;
Q.push(1);
inq[1] = neg[1] = 1, dis[1] = 0;
while(!Q.empty()) {
// cout << "*********" << endl;
int u = Q.front(); Q.pop();
inq[u] = 0;
for(int i = head[u]; ~i; i = e[i].next) {
int v = e[i].to, w = e[i].w;
if(dis[v] > dis[u] + w) {
dis[v] = dis[u] + w;
if(!inq[v]) {
inq[v] = 1;
neg[v]++;
if(neg[v] > n){ return -1;}
Q.push(v);
}
}
}
}
return dis[n] == inf ? -2 : dis[n];
}
int main() {
init();
scanf("%d%d%d", &n, &l, &d);
while(l--) {
int u = read(), v = read(), w = read();
addedge(u, v, w);
}
while(d--) {
int u = read(), v = read(), w = read();
addedge(v, u, -w);
}
for(int i = 1; i < n; i++) addedge(i + 1, i, 0);//??
printf("%d\n", spfa());
return 0;
}