差分约束+spfa+判断是否存在正环
#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<vector>
#include<queue>
#include<map>
const int maxn = 1000010;
const int inf = 0xffffff;
struct Edge{
int u,v,w;
}e[maxn];
int d[maxn],next[maxn],first[maxn],time[maxn],n,cnt[maxn];
bool inq[maxn];
using namespace std;
void add(int u,int v,int w,int ind){
e[ind].u=u;
e[ind].v=v;
e[ind].w=w;
next[ind]=first[u];
first[u]=ind;
}
bool spfa(){
int i;
memset(inq,false,sizeof(inq));
memset(cnt,0,sizeof(cnt));
for(i=1;i<=n;i++) d[i]=-inf;
d[0]=0;
queue<int> q;
q.push(0);
while(!q.empty()){
int x=q.front();
q.pop();
inq[x]=false;
for(i=first[x];i!=-1;i=next[i])
if(d[e[i].v]<d[x]+e[i].w){
d[e[i].v]=d[x]+e[i].w;
if(!inq[e[i].v]){
cnt[e[i].v]++;
if(cnt[e[i].v]>=n)
return false;
inq[e[i].v]=true;
q.push(e[i].v);
}
}
}
return true;
}
int main()
{
int i,j,u,v,c=0;
string op;
while(scanf("%d",&n),n){
for(i=1;i<=n;i++)
scanf("%d",&time[i]);
i=0;
memset(first,-1,sizeof(first));
while(cin>>op,op[0]!='#'){
scanf("%d%d",&v,&u);
if(op=="SAS") //感觉这不对劲啊,SAS过头了有可能变为SAF啊,这样也行?
add(u,v,0,i++);
else if(op=="SAF")
add(u,v,time[u],i++);
else if(op=="FAS")
add(u,v,-time[v],i++);
else
add(u,v,time[u]-time[v],i++);
}
for(j=1;j<=n;j++)
add(0,j,0,i++);
printf("Case %d:\n",++c);
if(spfa())
for(i=1;i<=n;i++)
printf("%d %d\n",i,d[i]);
else puts("impossible");
puts("");
}
return 0;
}