题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1534
基础差分约束;
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn = 1005;
const int inf = 1e9 + 7;
int l[maxn];
int n, m, cnt;
int head[maxn];
int mark[maxn];
int dis[maxn];
int vis[maxn];
struct P
{
int to;
int cost;
int next;
}edge[maxn * 2];
void add(int u, int v, int c)
{
edge[cnt].to = v;
edge[cnt].cost = c;
edge[cnt].next = head[u];
head[u] = cnt++;
}
bool spfa(int s = 0)
{
for(int i = 0; i < maxn; i++) dis[i] = inf;
memset(vis, 0 , sizeof(vis));
memset(mark, 0, sizeof(mark));
dis[s] = 0;
queue<int > Q;
Q.push(s);
vis[s] = 1;
mark[s]++;
while(!Q.empty())
{
int cur = Q.front(); Q.pop();
vis[cur] = 0;
if(mark[cur] > n + 1)
return 0;
for(int i = head[cur]; i != -1; i = edge[i].next)
{
int v = edge[i].to;
int c = edge[i].cost;
if(dis[v] > dis[cur] + c)
{
dis[v] = dis[cur] + c;
if(!vis[v])
{
Q.push(v);
vis[v] = 1;
mark[v]++;
}
}
}
}
return 1;
}
int main()
{
int C = 0;
while(cin >> n, n)
{
memset(head, -1, sizeof(head));
C++;
cnt = 0;
for(int i = 1; i <= n; i++)
{
scanf("%d", &l[i]);
}
string s;
while(cin >> s)
{
if(s == "#")
break;
int a, b;
cin >> a >> b;
if(s == "SAS")
{//xa >= xb + 1
add(b, a, -1);
}
else if(s == "FAF")
{//l[a] + xa >= l[b] + xb + 1
add(b, a, l[a] - l[b]);
}
else if(s == "SAF")
{//xa >= xb + l[b]
add(b, a, - l[b]);
}
else if(s == "FAS")
{//l[a] + xa >= xb
add(b, a, l[a]);
}
}
for(int i = 1; i <= n; i++)
{
add(0, i, 0);
}
printf("Case %d:\n", C);
if(spfa())
{
for(int i = 1; i <= n; i++)
{
printf("%d %d\n", i, -dis[i]);
}
cout << endl;
}
else
{
cout << "impossible" << endl << endl;
}
}
return 0;
}