又是一道单源最短路,pta真的很喜欢这个考点哈
#include <iostream>
#include <cstring>
#include <map>
#define N 210
using namespace std;
map<string,int> mp;
string ed,str[N];
int n,k,s,t;
int num[N],d[N][N];
int vis[N],dist[N],path[N],cnt[N],city[N],sum[N];
//path路径,cnt路径条数,city路径上城市数,sum路径上敌军总数
void dijk(){
memset(dist,0x3f,sizeof dist);
for(int i=1;i<=n;i++){
if(d[s][i]){//初始可到达点
dist[i]=d[s][i];
path[i]=s;
cnt[i]=cnt[s]+1;
city[i]=city[s]+1;
sum[i]=sum[s]+num[i];
}
}
dist[s]=0;
vis[s]=1;
for(int k=1;k<n;k++){
int mind=0x3f3f3f3f,p=-1;
for(int i=1;i<=n;i++)
if(!vis[i]&&dist[i]<mind) mind=dist[i],p=i;
if(p==t) break;
vis[p]=1;
for(int i=1;i<=n;i++){
if(!vis[i]&&d[p][i]){
if(dist[i]>dist[p]+d[p][i]){//路径变短
dist[i]=dist[p]+d[p][i];
path[i]=p;
cnt[i]=cnt[p];
city[i]=city[p]+1;
sum[i]=sum[p]+num[i];
}
else if(dist[i]==dist[p]+d[p][i]){//路径长度相同
cnt[i]+=cnt[p];
if(city[i]<city[p]+1){//城市数增多
path[i]=p;
city[i]=city[p]+1;
sum[i]=sum[p]+num[i];
}
else if(city[i]==city[p]+1&&sum[i]<sum[p]+num[i]){//敌军数增多
path[i]=p;
sum[i]=sum[p]+num[i];
}
}
}
}
}
}
int main(){
cin>>n>>k;
cin>>str[1]>>ed;
mp[str[1]]=1; s=1;
for(int i=2;i<=n;i++){
cin>>str[i]>>num[i];
mp[str[i]]=i;//离散化
if(str[i]==ed) t=i;
}
for(int i=1;i<=k;i++){
string u,v;
int w;
cin>>u>>v>>w;
d[mp[u]][mp[v]]=d[mp[v]][mp[u]]=w;
}
dijk();
int ans[N],id=0,p=t;//路径
ans[++id]=p;
while(path[p]!=s){
ans[++id]=path[p];
p=path[p];
}
cout<<str[s];
for(;id;id--) cout<<"->"<<str[ans[id]];
printf("\n%d %d %d\n",cnt[t],dist[t],sum[t]);
return 0;
}