Input
The input file consists a sequences of projects.
Each project consists the following lines:
the count number of parts (one line) (0 for end of input)
times should be taken to complete these parts, each time occupies one line
a list of FAS, FAF, SAF or SAS and two part number indicates a constrain of the two parts
a line only contains a '#' indicates the end of a project
Output
Output should be a list of lines, each line includes a part number and the time it should start. Time should be a non-negative integer, and the start time of first part should be 0. If there is no answer for the problem, you should give a non-line output containing "impossible".
A blank line should appear following the output for each project.
Sample Input
3
2
3
4
SAF 2 1
FAF 3 2
#
3
1
1
1
SAF 2 1
SAF 3 2
SAF 1 3
#
0
Sample Output
Case 1:
1 0
2 2
3 1
impossible
这题还是挺简单的,对于四种模式,分别建立不同的边,设s[i]表示第i个部分的开始时间,t[i]表示其持续时间
FAS:s[i] + t[i] >= s[j]
FAF:s[i] + t[i] >= s[j] + t[j]
SAF:s[i] >= s[j] + t[j]
SAS:s[i] >= s[j]
由于题目要求的是the short time,所以只要求最长路就可以了,因图可能不连通,所以加一个超级源点0,到每个点的权值是0
#include <map> #include <set> #include <list> #include <stack> #include <vector> #include <queue> #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int N = 1010; const int M = 200010; const int inf = 0x3f3f3f3f; queue <int>qu; int tot, n, m; int head[N]; int t[N]; int dist[N]; int in_queue[N]; struct node { int weight; int next; int to; }edge[M]; void addedge(int from, int to, int weight) { edge[tot].weight = weight; edge[tot].to = to; edge[tot].next = head[from]; head[from] = tot++; } bool spfa(int v0) { memset (dist, -inf, sizeof(dist) ); memset (in_queue, 0, sizeof(in_queue) ); dist[v0] = 0; in_queue[v0]++; while ( !qu.empty() ) { qu.pop(); } qu.push(v0); while ( !qu.empty() ) { int u = qu.front(); qu.pop(); for (int i = head[u]; ~i; i = edge[i].next) { int v = edge[i].to; if (dist[v] < dist[u] + edge[i].weight) { dist[v] = dist[u] + edge[i].weight; in_queue[v]++; if (in_queue[v] == n + 1) { return false; } qu.push(v); } } } return true; } int main() { int icase = 1; while (~scanf("%d", &n), n) { memset (head, -1, sizeof(head) ); tot = 0; char str[10]; int u, v; for (int i = 1; i <= n; ++i) { scanf("%d", &t[i]); } while (scanf("%s", str)) { if (str[0] == '#') { break; } scanf("%d%d", &u, &v); if (!strcmp(str, "FAS")) { addedge(v, u, -t[u]); } else if (!strcmp(str, "FAF")) { addedge(v, u, t[v] - t[u]); } else if (!strcmp(str, "SAF")) { addedge(v, u, t[v]); } else { addedge(v, u, 0); } } for (int i = 1; i <= n; ++i) { addedge(0, i, 0); } printf("Case %d:\n", icase++); bool flag = spfa(0); if (!flag) { printf("impossible\n\n"); continue; } for (int i = 1; i <= n; ++i) { printf("%d %d\n", i, dist[i]); } printf("\n"); } return 0; }