【题意】:给出n个任务以及他们的运行时间t[i].其中有4种依赖关系: FAS, FAF, SAF和SAS. F—finish,S—start,A—after.给出很多组关系,
[ FAS i j ]表示i的finish要发生在j的start之后,其他关系以此类推.
求一种调度方案使时间最短并输出每个任务的开始时间.
【题解】:设s[i]为任务i的开始时间,v[i]为任务i的运行时间:
对于每种限制,都可以转化为不等式关系。
SAF a b => s[a] >= s[b] + val[b];
FAF a b => s[a] + v[a] >= s[b] + v[b];
SAS a b => s[a] >= s[b];
FAS a b => s[a] + v[a] >= s[b];
题目有一个条件是是第一个任务开始时间必须为0,还有一个隐含条件是所有任务的开始时间必须大于等于0.
构造一个差分约束系统求最长路既可得到每个任务的最短开始时间。
【代码】:
1 #include "iostream"
2 #include "cstdio"
3 #include "cstring"
4 #include "algorithm"
5 #include "vector"
6 #include "queue"
7 #include "cmath"
8 #include "string"
9 #include "cctype"
10 #include "map"
11 #include "iomanip"
12 using namespace std;
13 #define pb push_back
14 #define mp make_pair
15 #define fi first
16 #define se second
17 #define lc(x) (x << 1)
18 #define rc(x) (x << 1 | 1)
19 #define lowbit(x) (x & (-x))
20 #define ll long long
21 #define maxn 10050
22 #define maxm 500000
23 const int inf = 1 << 29;
24 struct Edge {
25 int u, v, cost, next;
26 } et[maxm];
27
28 int eh[maxn], tot, dist[maxn], cnt[maxn];
29 bool visit[maxn];
30 int n, m;
31 int val[maxn];
32 int s;
33
34 void init() {
35 tot = 0;
36 memset(eh, -1, sizeof (eh));
37 }
38
39 void addedge(int u, int v, int cost) {
40 Edge e = {u, v, cost, eh[u]};
41 et[tot] = e;
42 eh[u] = tot++;
43 }
44
45 bool spfa(int s) {
46 for (int i = 0; i <= n; i++) visit[i] = false, dist[i] = -inf, cnt[i] = 0;
47 dist[s] = 0, visit[s] = true, cnt[s]++;
48 queue<int> que;
49 que.push(s);
50 while (!que.empty()) {
51 int u = que.front();
52 que.pop(), visit[u] = false;
53 for (int i = eh[u]; i != -1; i = et[i].next) {
54 int v = et[i].v, cost = et[i].cost;
55 if (dist[v] < cost + dist[u]) {
56 dist[v] = cost + dist[u];
57 if (!visit[v]) {
58 visit[v] = true;
59 que.push(v);
60 cnt[v]++;
61 if (cnt[v] >= n + 1) return false;
62 }
63 }
64 }
65 }
66 return true;
67 }
68
69 int main() {
70 string s;
71 int Case = 1;
72 while(~scanf("%d", &n)) {
73 if(!n) break;
74 init();
75 for(int i = 1; i <= n; i++) {
76 scanf("%d", &val[i]);
77 addedge(0, i, 0);
78 }
79 addedge(1, 0, 0);
80 int a, b;
81 while(1) {
82 cin >> s;
83 if(s == "#") break;
84 scanf("%d%d", &a, &b);
85 if(s == "SAF") addedge(b, a, val[b]);
86 else if(s == "FAF") addedge(b, a, val[b] - val[a]);
87 else if(s == "SAS") addedge(b, a, 0);
88 else if(s == "FAS") addedge(b, a, -val[a]);
89 }
90 printf("Case %d:\n", Case++);
91 if(spfa(0)) {
92 for(int i = 1; i <= n; i++) {
93 printf("%d %d\n", i, dist[i]);
94 }
95 } else printf("impossible\n");
96 printf("\n");
97 }
98 return 0;
99 }
100