zoj 1455 Schedule Problem 差分约束
设d[i]为 第i个工作开始的时间,根据题意有:
FAS a b: d[a] + time[a] >= d[b]
FAF a b: d[a] + time[a] >= d[b] + time[b]
SAF a b: d[a] >= d[b] + time[b]
SAS a b: d[a] >= d[b]
还有: d[i] >= 0 即 d[i] – d[0] >= 0
以0为源点开始搜索,0是超源点
#include <iostream> #include <queue> #include <cstring> #include <cstdio> using namespace std; const int MAX = 100000; const int N = 10000; const int INF = 1000000000; struct Node { int v; int cost; int next; }; Node node[MAX]; int cnt[N]; int adj[N]; bool in_q[N]; int d[N], times[N]; int n; int size; void add_edge(int u, int v, int cost) { node[size].v = v; node[size].cost = cost; node[size].next = adj[u]; adj[u] = size++; } bool spfa() { queue<int> Q; memset(cnt, 0, sizeof(cnt)); memset(in_q, false, sizeof(in_q)); for (int i = 0; i <= n; i++) d[i] = -INF; d[0] = 0; Q.push(0); in_q[0] = true; int u, v, w; while (!Q.empty()) { u = Q.front(); Q.pop(); in_q[u] = false; for (int i = adj[u]; i != -1; i = node[i].next) { v = node[i].v; w = node[i].cost; if (d[v] < d[u] + w) { d[v] = d[u] + w; if (!in_q[v]) { in_q[v] = true; Q.push(v); if (++cnt[v] > n) return false; } } } } return true; } int main() { char c[20]; int a, b; int cases = 1; while (scanf("%d", &n) != EOF) { if (n == 0) break; size = 0; for (int i = 0; i <= n; i++) adj[i] = -1; for (int i = 1; i <= n; i++) scanf("%d", ×[i]); while (1) { getchar(); scanf("%s", c); if (strcmp(c, "#") == 0) break; else if (strcmp(c, "FAS") == 0) { scanf("%d%d", &a, &b); add_edge(b,a, -times[a]); } else if (strcmp(c, "FAF") == 0) { scanf("%d%d", &a, &b); add_edge(b,a, times[b]-times[a]); } else if (strcmp(c, "SAF") == 0) { scanf("%d%d", &a, &b); add_edge(b, a, times[b]); } else if (strcmp(c, "SAS") == 0) { scanf("%d%d", &a, &b); add_edge(b, a, 0); } } for (int i = 1; i <= n; i++) add_edge(0, i, 0); printf("Case %d:\n", cases++); if (spfa()) { for (int i = 1; i <= n; i++) printf("%d %d\n", i, d[i]); } else printf("impossible\n"); printf("\n"); } return 0; }