题目链接:https://www.patest.cn/contests/pat-a-practise/1003
题目大意: 给一个图,求所给两点之间的最短路径的条数,以及这些最短路径中,哪条路径经过的所有节点的权值和最大。
解题思路:使用Dijkstra最短路径算法。
edge[i][j]:表示i到j的距离
weight[i]:表示节点i的权值
dist[i]:表示从所给的起点到i点的最短路径
wi[i]:表示从所给的起点到i点的最大权值和
pathcnt[i]:表示从所给的起点到i点的最短路径条数
代码如下
#include <iostream>
#include <algorithm>
using namespace std;
const int inf=100000000;
int edge[501][501];//元素值为边距离
int weight[501];//城市救援队数
int dist[501];//dist[i]为从出发点到i点的最短路径长度
int wi[501];//出发点到i点的救援队总数
int pathcnt[501];//最短路径的条数
int main(int argc, char const *argv[])
{
int n,m,c1,c2;
cin>>n>>m>>c1>>c2;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
edge[i][j]=inf;//初始化边的距离
for(int i=0;i<n;i++){
cin>>weight[i];//输入节点权值
dist[i]=inf;//最短距离初始化
}
int src,des,dis;
for(int i=0;i<m;i++){
cin>>src>>des>>dis;//输入每条边
edge[src][des]=dis;
edge[des][src]=dis;
}
dist[c1]=0;
wi[c1]=weight[c1];
pathcnt[c1]=1;
int visit[501]={0};
/*使用dijkstra算法求出c1到每个点的最短路径*/
for(int i=0;i<n;i++){
int current=-1,min=inf;
/*先找当前距离c1点的最短距离,
以及最短路径上的终点*/
for(int j=0;j<n;j++){
if(visit[j]==0&&dist[j]<min){
current=j;
min=dist[j];
}
}
if(current==-1)
break;
visit[current]=1;
/*向外扩张,更新最短距离*/
for(int j=0;j<n;j++){
if(visit[j]==0&&edge[current][j]!=inf){//当前节点为曾访问,且可达current
if(dist[current]+edge[current][j]<dist[j]){//找到更短的路径
dist[j]=dist[current]+edge[current][j];//更新路径
wi[j]=wi[current]+weight[j];//更新节点权值和
pathcnt[j]=pathcnt[current];//更新路径数量
}
else if(dist[current]+edge[current][j]==dist[j]){//相同路径相同
pathcnt[j]=pathcnt[current]+pathcnt[j];//更新路径数量
if(wi[j]<wi[current]+weight[j])//更新总节点权值
wi[j]=wi[current]+weight[j];
}
}
}
}
cout<<pathcnt[c2]<<" "<<wi[c2]<<endl;
return 0;
}