题目意思
给出你四个整数N,M,S,D,分别表示有N个城市,城市标号从0~(n-1),连接M条路。接下来给你N个数代表第几个城市有多少救援队,接下来的M行给出你三个数a ,b, l 分别代表从城市a到城市b距离l。现在要你输出总共有几条最短路径且最短路径上的最多的救援队的数量,并且输出拥有最多的救援队的路径。
解题思路
这是一道用dijstra 算法求最短路的题目。不过题目不但要求最短路径,并且要输出最短路径的条数和最短路径。那么我们就用path数组来记录路径,path【u】表示u的前驱节点。
代码部分
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=510;
const int INF=0x3f3f3f3f;
int n,m,s,d;
int maps[maxn][maxn];///存储两点间的距离
int dis[maxn],path[maxn],pathnum[maxn],val[maxn],totalval[maxn],re[maxn];///totalval数组记录救援队最多的数量,re数组记录救援队最多的路径
int vis[maxn];///标记数组
void dijstra(int u,int v)
{
int pos=u;
for(int i=0; i<n; i++)
{
dis[i]=INF;
}
memset(vis,0,sizeof(vis));
vis[u]=1;
dis[u]=0;
totalval[u]=val[u];
pathnum[u]=1;///pathnum数组表示最短路径的条数
for(int i=0; i<n; i++)
{
if(maps[u][i]!=INF&&i!=u)
{
dis[i]=maps[u][i];
path[i]=u;
totalval[i]=val[u]+val[i];
pathnum[i]=1;
}
}
for(int i=0; i<n-1; i++)
{
int minn=INF,minval=0;
for(int j=0; j<n; j++)
{
if(!vis[j]&&minn>dis[j])
{
minn=dis[j];
pos=j;
}
}
vis[pos]=1;
for(int j=0; j<n; j++)
{
if(!vis[j])
{
if(maps[pos][j]+dis[pos]<dis[j])
{
pathnum[j]=pathnum[pos];
dis[j]=maps[pos][j]+dis[pos];
totalval[j]=totalval[pos]+val[j];
path[j]=pos;
}
else if(maps[pos][j]+dis[pos]==dis[j])
{
pathnum[j]+=pathnum[pos];
if(totalval[j]<totalval[pos]+val[j])
{
totalval[j]=totalval[pos]+val[j];
path[j]=pos;
}
}
}
}
}
}
int main()
{
scanf("%d%d%d%d",&n,&m,&s,&d);
for(int i=0; i<n; i++)
scanf("%d",&val[i]);
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
maps[i][j]=INF;
int a,b,l;
for(int i=0; i<m; i++)
{
scanf("%d%d%d",&a,&b,&l);
maps[a][b]=maps[b][a]=min(maps[a][b],l);
}
dijstra(s,d);
int num=0,cur=d;
while(cur!=s)
{
re[num++]=cur;
cur=path[cur];
}
re[num++]=s;
printf("%d %d\n",pathnum[d],totalval[d]);
for(int i=num-1; i>0; i--)
printf("%d ",re[i]);
printf("%d\n",re[0]);
return 0;
}