poj Layout
注意:最大值不存在的情况输出\(-1\),最大值无穷大的情况输出\(-2\)
poj上有多组测试
洛谷有\(hack\)数据
怎么连边
因为这是一个,我不喜欢你,我要和你挨得远,喜欢你就挨得近的问题
\(u\)与\(v\)最多可相隔\(d\)就变成了\(v-u<=d\)
可以从\(u\)连向\(v\)的一条边权为\(d\)的一条边
\(u\)与\(v\)最小相隔\(d\)就变成了\(v-u>=d\),然后我们取负号就变成了
\(u-v <= -d\),即从\(v\)连向\(u\)的一条\(-d\)的边
for (int i = 1, x, y, d; i <= m1; i++) {
x = read(), y = read(), d = read();
add(x, y, d);
}
for (int i = 1, x, y, d; i <= m2; i++) {
x = read(), y = read(), d = read();
add(y, x, -d);
}
操作
因为这是一个排队,所以\(i\)与\(i+1\)之间要连边
for (int i = 1; i < n; i++)
add(i + 1, i, 0);
而且我们需要判断有无负环,所以开一个超级源点判断一下有无解.
for (int i = 1; i <= n; i++)
add(0, i, 0);
code
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
#define N 20010
#define M 1010
using namespace std;
struct node {
int next, to, dis;
} edge[N << 1];
int dis[M], vis[M], n, m1, m2;
int point[M];
int head[N << 1], add_edge;
int read() {
int s = 0, f = 0;
char ch = getchar();
while (!isdigit(ch)) f |= (ch == '-'), ch = getchar();
while (isdigit(ch)) s = s * 10 + (ch ^ 48), ch = getchar();
return f ? -s : s;
}
void add(int from, int to, int dis) {
edge[++add_edge].next = head[from];
edge[add_edge].to = to;
edge[add_edge].dis = dis;
head[from] = add_edge;
}
int spfa(int st) {
memset(vis, 0, sizeof vis);
memset(dis, 0x3f, sizeof dis);
memset(point, 0, sizeof point);
queue<int> q;
dis[st] = 0;
q.push(st);
vis[st] = 1, dis[st] = 0;
while (!q.empty()) {
int fr = q.front();
q.pop(), vis[fr] = 0;
for (int i = head[fr]; i; i = edge[i].next) {
int to = edge[i].to;
if (dis[to] > dis[fr] + edge[i].dis) {
dis[to] = dis[fr] + edge[i].dis;
if (!vis[to]) {
point[to]++;
if (point[to] == n) return -1;
vis[to] = 1, q.push(to);
}
}
}
}
if (dis[n] == 0x3f3f3f3f) return -2;
else return dis[n];
}
int main() {
while (scanf("%d%d%d", &n, &m1, &m2) != EOF) {
for (int i = 1; i < n; i++)
add(i + 1, i, 0);
for (int i = 1; i <= n; i++)
add(0, i, 0);
for (int i = 1, x, y, d; i <= m1; i++) {
x = read(), y = read(), d = read();
add(x, y, d);
}
for (int i = 1, x, y, d; i <= m2; i++) {
x = read(), y = read(), d = read();
add(y, x, -d);
}
int sy = spfa(0);
if (sy <= -1) {
cout << sy << "\n";
continue;
} else cout << spfa(1);
}
}