题目链接:点击进入
思路
最短路+dfs路径回溯,不难,但是我又被卡了,没看出来最短距离相等时,路径数应该是两者相加(我记得我之前做这类的题目的时候也是这里被卡,我真是猪脑子(* ̄(oo) ̄))。。。写博客纪念一下o(╥﹏╥)o
代码
#include<iostream>
#include<cstring>
#include<queue>
#include<map>
#include<cstdio>
#define pii pair<int,int>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=1e5+10;
int n,k,tot,be,en,x,pre[210];
int c[210];//记录城镇的敌人数量
int dis[210],head[210],cnt;
int path[210];//记录到这个点的最短路径有几条
int kill[210];//记录杀敌数
int city[210];//记录经过几个城市
bool vis[210];
string s,ss;
map<string,int>mp;
map<int,string>mp2;
struct node
{
int w;
int to;
int next;
}edge[maxn];
void init()
{
memset(head,-1,sizeof(head));
memset(dis,INF,sizeof(dis));
cnt=0;
}
void add(int u,int v,int w)
{
edge[cnt].w=w;
edge[cnt].to=v;
edge[cnt].next=head[u];
head[u]=cnt++;
}
void dijkstra(int s)
{
priority_queue<pii,vector<pii>,greater<pii> >q;
dis[s]=0;q.push({dis[s],s});
city[s]=1;path[s]=1;kill[s]=c[s];
while(q.size())
{
int now=q.top().second;
q.pop();
if(vis[now]) continue;
vis[now]=1;
for(int i=head[now];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(dis[v]>dis[now]+edge[i].w)
{
dis[v]=dis[now]+edge[i].w;
pre[v]=now;
path[v]=path[now];//更新最短路径条数
//最短距离被更新,所以到 v 点的最短路径条数 = 到 now 点的最短路径条数
city[v]=city[now]+1;//城镇 + 1
kill[v]=kill[now]+c[v];//杀敌数 + 这个城镇的敌人数
q.push({dis[v],v});
}
else if(dis[v]==dis[now]+edge[i].w)
{
path[v]=path[v]+path[now];
// 最短距离没变,但是到 v 点的最短路径条数增加了,要加上到 now 点的最短路径条数
//这里我被卡了o(╥﹏╥)o,所以写博客纪念一下
if(city[v]<city[now]+1)
{
city[v]=city[now]+1;
kill[v]=kill[now]+c[v];
pre[v]=now;
}
else if(city[v]==city[now]+1)
{
if(kill[v]<kill[now]+c[v])
{
kill[v]=kill[now]+c[v];
pre[v]=now;
}
}
}
}
}
}
void print(int p)
{
if(p==be)
{
cout<<mp2[p];
return ;
}
else
{
print(pre[p]);
cout<<"->"<<mp2[p];
}
}
int main( )
{
ios::sync_with_stdio(false);
init();
cin>>n>>k;
cin>>s>>ss;
mp[s]=++tot;
mp2[tot]=s;
be=tot;
if(!mp.count(ss)) mp[ss]=++tot,mp2[tot]=ss;
en=tot;
for(int i=1;i<n;i++)
{
cin>>s>>x;
if(!mp.count(s)) mp[s]=++tot,mp2[tot]=s;
c[mp[s]]=x;
}
for(int i=1;i<=k;i++)
{
cin>>s>>ss>>x;
add(mp[s],mp[ss],x);
add(mp[ss],mp[s],x);
}
dijkstra(be);
print(en);
cout<<endl;
cout<<path[en]<<' '<<dis[en]<<' '<<kill[en];
return 0;
}