$n$ 只母牛排成队吃饭,用 $s_i$ 表示第 i 只母牛的位置,这些位置有这些限制:
1. $s_i \le s_{i+1}$
2. 给出 ML 个限制:$s_b - s_a \le d$
2. 给出 MD 个限制:$s_b - s_a \ge d$
问 1 牛到 n 牛的最大距离。
这个显然是查分约束。
#include <stdio.h> #include <string.h> #include <assert.h> #include <vector> #include <queue> using namespace std; struct Edge { int cost; int target; Edge(int targetI = 0, int costI = 0): target(targetI), cost(costI) {}; }; vector<vector<Edge> > G; queue<int> q; const int MAXN = 10000 + 5; bool inq[MAXN]; int inqCnt[MAXN]; long long dis[MAXN]; const long long INF = 0x7f7f7f7f7f7f7f7f; long long bellmanFord(int n) { memset(inq, 0, sizeof(bool) * (n + 1)); memset(inqCnt, 0, sizeof(int) * (n + 1)); memset(dis, 0x7f, sizeof(long long) * (n + 1)); assert(INF == dis[0]); dis[1] = 0; q.push(1); inq[1] = true; inqCnt[1] = 1; for (; !q.empty(); ) { int u = q.front(); q.pop(); inq[u] = false; for (int i = 0; i < G[u].size(); i++) { int v = G[u][i].target; int cost = G[u][i].cost; if (dis[v] > dis[u] + cost) { dis[v] = dis[u] + cost; if (!inq[v]) { q.push(v); inqCnt[v]++; inq[v] = true; if (inqCnt[v] == n) return -1; } } } } if (dis[n] == INF) return -2; return dis[n]; } int main() { int n, ml, md; scanf("%d %d %d", &n, &ml, &md); G.resize(n + 1); int u, v, d; for (int i = 0; i < ml; i++) { scanf("%d %d %d", &u, &v, &d); // s[v] - s[u] <= d G[u].push_back(Edge(v, d)); } for (int i = 0; i < md; i++) { scanf("%d %d %d", &u, &v, &d); // s[v] - s[u] >= d // s[u] - s[v] <= -d G[v].push_back(Edge(u, -d)); } // s[i] - s[i+1] <= 0 for (int i = 1; i < n; i++) G[i+1].push_back(Edge(i, 0)); printf("%I64d\n", bellmanFord(n)); return 0; } /* 4 2 1 1 3 10 2 4 20 2 3 3 */
原文:http://www.cnblogs.com/gu-castle/p/5003472.html