增加一维记录走过的步数进行SPFA即可,最后注意从小到大更新结果。
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#include <map>
#include <string>
#include <utility>
using namespace std;
typedef pair<int,int> pii;
const int maxn=110;
const int maxm=2000;
const int inf=1<<30;
map<string,int> name;
int n,m,q,e;
int head[maxn],pnt[maxm],nxt[maxm],cost[maxm];
int d[maxn][maxn],vis[maxn][maxn];
void addedge(int u,int v,int c)
{
pnt[e]=v;cost[e]=c;nxt[e]=head[u];head[u]=e++;
}
void bellmanford()
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
d[i][j]=inf,vis[i][j]=0;
queue<pii> q;
int s=name["Calgary"];
q.push(make_pair(s,0));
d[s][0]=0;vis[s][0]=1;
while(!q.empty())
{
pii p=q.front();q.pop();
int u=p.first,ud=p.second;
vis[u][ud]=0;
for(int i=head[u];i!=-1;i=nxt[i])
{
int v=pnt[i],c=cost[i],vd=ud+1;
if(d[v][vd]>d[u][ud]+c)
{
d[v][vd]=d[u][ud]+c;
if(!vis[v][vd])
{
vis[v][vd]=1;
q.push(make_pair(v,vd));
}
}
}
}
for(int i=0;i<n;i++)
for(int j=1;j<n;j++)
d[i][j]=min(d[i][j],d[i][j-1]);
}
int main()
{
int T,kase=1;
cin>>T;
while(T--)
{
cin>>n;
name.clear();
for(int i=0;i<n;i++)
{
string s;
cin>>s;
name[s]=i;
}
cin>>m;
memset(head,-1,sizeof(head));
e=0;
for(int i=0;i<m;i++)
{
string s1,s2;
int u,v,c;
cin>>s1>>s2>>c;
u=name[s1],v=name[s2];
addedge(u,v,c);
}
int t=name["Fredericton"];
bellmanford();
cin>>q;
cout<<"Scenario #"<<kase++<<endl;
while(q--)
{
int limit;
cin>>limit;
if(limit+1>=n) cout<<"Total cost of flight(s) is $"<<d[t][n-1]<<endl;
else if(d[t][limit+1]==inf) cout<<"No satisfactory flights"<<endl;
else cout<<"Total cost of flight(s) is $"<<d[t][limit+1]<<endl;
}
if(T) puts("");
}
return 0;
}