1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
| #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <queue> using namespace std;
const int maxN = 10005;
int n, head[maxN], nowCase, cost[maxN], cnt, vis[maxN], op[maxN], dis[maxN];
class Edge { public: int nxt, to, dis; };
Edge e[maxN << 2];
inline void addEdge(int u, int v, int w) { e[++cnt].nxt = head[u]; head[u] = cnt; e[cnt].to = v; e[cnt].dis = w; };
inline bool spfa(int st, int ed) { memset(vis, 0, sizeof(vis)); memset(dis, 0x3f, sizeof(dis)); memset(op, 0, sizeof(op)); queue<int> q; q.push(st); vis[st] = 1, dis[st] = 0;
while(!q.empty()) { int now = q.front(); q.pop(); vis[now] = 0; ++op[now]; if(op[now] >= n) return true;
for(int i = head[now], y; i; i = e[i].nxt) { if(dis[y = e[i].to] > dis[now] + e[i].dis) { dis[y] = dis[now] + e[i].dis; if(!vis[y]) { vis[y] = 1;q.push(y); } } } } return false; }
int main() { while(~scanf("%d", &n)) { if(n == 0) break;
cnt = 0; memset(head, 0 ,sizeof(head));
for(int i = 1; i <= n; ++i) scanf("%d", &cost[i]); char mode[10]; while(~scanf("%s", mode)) { if(mode[0] == '#') break; int x, y; scanf("%d%d", &x, &y); if(strcmp(mode, "FAF") == 0) addEdge(x, y, cost[x] - cost[y]); else if(strcmp(mode, "FAS") == 0) addEdge(x, y, cost[x]); else if(strcmp(mode, "SAF") == 0) addEdge(x, y, -cost[y]); else if(strcmp(mode, "SAS") == 0) addEdge(x, y, 0); } for(int i = 1; i <= n; ++i) addEdge(0, i, 0); bool isFailed = spfa(0, n + 1);
printf("Case %d:\n", ++nowCase); if(isFailed) printf("impossible\n"); else { int minT = 0x3f3f3f3f; for(int i = 1; i <= n; ++i) minT = min(minT, dis[i]); for(int i = 1; i <= n; ++i) printf("%d %d\n", i, dis[i] - minT); } printf("\n"); } return 0; }
|