思路:一道差分约束最长路求最小值,读懂题目连边求一次最长路就可以了
#include<bits/stdc++.h>
using namespace std;
const int maxn = 10010;
#define inf 1e9
vector<pair<int,int> >e[maxn];
int d[maxn],inq[maxn],a[maxn],cnt[maxn];
int n;
int spfa()
{
memset(inq,0,sizeof(inq));
memset(cnt,0,sizeof(cnt));
for(int i = 0;i<=n;i++)
d[i]=-inf;
queue<int>q;
q.push(0);
inq[0]=1;
d[0]=0;
while(!q.empty())
{
int u = q.front();
q.pop();
inq[u]=0;
for(int i = 0;i<e[u].size();i++)
{
int v = e[u][i].first;
if(d[v]<d[u]+e[u][i].second)
{
d[v]=d[u]+e[u][i].second;
if(!inq[v])
{
inq[v]=1;
q.push(v);
if(++cnt[v]>n)
return false;
}
}
}
}
return true;
}
int main()
{
int cas = 1;
while(scanf("%d",&n)!=EOF && n)
{
for(int i = 0;i<=n;i++)
e[i].clear();
for(int i = 1;i<=n;i++)
scanf("%d",&a[i]);
char s[105];
while(scanf("%s",s) && strcmp(s,"#")!=0)
{
int u,v;
scanf("%d%d",&u,&v);
if(strcmp(s,"FAS")==0)
e[v].push_back(make_pair(u,-a[u]));
if(strcmp(s,"FAF")==0)
e[v].push_back(make_pair(u,a[v]-a[u]));
if(strcmp(s,"SAF")==0)
e[v].push_back(make_pair(u,a[v]));
if(strcmp(s,"SAS")==0)
e[v].push_back(make_pair(u,0));
}
for(int i = 1;i<=n;i++)
e[0].push_back(make_pair(i,0));
printf("Case %d:\n",cas++);
if(spfa())
{
for(int i = 1;i<=n;i++)
printf("%d %d\n",i,d[i]);
}
else
printf("impossible\n");
printf("\n");
}
}