题解
最短路径经典题型。套最短路的板子再加上额外的要求就可以了(说起来好简单)。SPFA也行,Dijkstra也可以。这里我用的是SPFA。因为题目要求,将地名和其对应的数字用map映射一下,这样方便处理。
same[i]代表到达地点 i 有几种路径;
dist[i]代表从起点到地点 i 的最短距离;
happy[i]代表从起点到地点 i 的幸福值;
cnt[i]代表从起点到地点 i 需要经过几个城市;
ans[i]代表从哪个地点到达了地点 i ;
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=250,inf=0x3fffffff;
struct node
{
int v,w;
node(int a,int b)
{v=a;w=b;}
};
int same[maxn]={0,1},dist[maxn],vis[maxn],happy[maxn],cnt[maxn],ans[maxn];
int value[maxn],N,K;
map<string,int> smapi;
map<int,string> imaps;
vector<node> edge[maxn];
void spfa(int s);
void print(int p);
int main()
{
string str_s,str,u,v;
int i,w,end;
scanf("%d%d",&N,&K);
cin>>str_s;
smapi[str_s]=1; imaps[1]=str_s;
for(i=2;i<=N;i++)
{
cin>>str>>w;
if(str=="ROM") end=i;
smapi[str]=i; imaps[i]=str;
value[i]=w;
}
for(i=0;i<K;i++)
{
cin>>u>>v>>w;
edge[smapi[u]].push_back(node(smapi[v],w));
edge[smapi[v]].push_back(node(smapi[u],w));
}
spfa(1);
printf("%d %d %d %d
",same[end],dist[end],happy[end],happy[end]/cnt[end]);
print(ans[end]);
printf("ROM");
system("pause");
return 0;
}
void print(int p)
{
if(p==0) return ;
print(ans[p]);
printf("%s->",imaps[p].c_str());
}
void spfa(int s)
{
queue<int> que;
int p,i,v,w;
fill(dist+2,dist+maxn,inf);
que.push(s);
while(!que.empty())
{
p=que.front();que.pop();
vis[p]=0;
for(i=0;i<edge[p].size();i++)
{
v=edge[p][i].v;
w=edge[p][i].w;
if(dist[v]>dist[p]+w)
{
dist[v]=dist[p]+w;
happy[v]=happy[p]+value[v];
cnt[v]=cnt[p]+1;
ans[v]=p;
same[v]=same[p];
if(!vis[v])
{
que.push(v);
vis[v]=1;
}
}
else if(dist[v]==dist[p]+w)
{
same[v]+=same[p];
if(happy[v]<happy[p]+value[v])
{
happy[v]=happy[p]+value[v];
cnt[v]=cnt[p]+1;
ans[v]=p;
}
else if(happy[p]+value[v]==happy[v])
{
if(cnt[v]>cnt[p]+1)
{
cnt[v]=cnt[p]+1;
ans[v]=p;
}
}
}
}
}
}