题目链接:
https://pintia.cn/problem-sets/994805342720868352/problems/994805523835109376
题目大意:
这是一道图中最短路径的题目。只是增加了一个条件,在最短路径中选择顶点的权值最大者。本例中使用dijkstra算法。
参考代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxv=510;
const int inf=1000000000;
i
int n,m,st,ed,G[maxv][maxv],weight[maxv]; //存储结构使用邻接矩阵
int d[maxv],w[maxv],num[maxv]; //d[i]表示源点到i的最短距离,w[i]表示该路径的权重
bool vis[maxv]={false}; //num[i]表示到i的最短路径条数,vis[i]表示该节点是否被访问
void Dijkstra(int s){
fill(d,d+maxv,inf);
memset(num,0,sizeof(num)); //fill(num, num + maxv, 0);同样可以
memset(w,0,sizeof(w));
d[s]=0; w[s]=weight[s]; num[s]=1; //分别初始化d, w, num。
for(int i=0;i<n;i++){ //一轮循环确定一个最短路径上的节点。
int u=-1, min=inf;
for(int j=0;j<n;j++){
if(vis[j]==false&&d[j]<min)
{
u=j, min=d[j];
}
}
if(u==-1) return; //表示已访问完源节点所在的连通分量的所有节点
vis[u]=true;
for(int v=0;v<n;v++){
if(vis[v]==false&&G[u][v]!=inf){ //遍历所有未访问过的节点,若存在更短的路径,更新路径
if(d[v]>d[u]+G[u][v]){
d[v]=d[u]+G[u][v];
w[v]=w[u]+weight[v];
num[v]=num[u]; //当通过u到达v路径长度更短时,则到达u的最短路径条数与
//到达v的最短路径条数相同
}else if(d[u]+G[u][v] == d[v]){
if(w[u]+weight[v]>w[v]){ //同样的路径长度,存在更大的权值,更新路径
w[v]=w[u]+weight[v];
}
num[v]+=num[u]; //当通过u到达v路径长度等于最短路径时,则到达u的最短路径条数为
//此前到达v的最短路径条数加上到达u的最短路径条数
}
}
}
}
}
int main(){
scanf("%d%d%d%d",&n,&m,&st,&ed);
for(int i=0;i<n;i++){ //weight[]记录各个城市医疗队的数量
scanf("%d",&weight[i]);
}
int u,v;
fill(G[0],G[0]+maxv*maxv,inf); //邻接矩阵初始化
for(int i=0;i<m;i++){
scanf("%d%d",&u,&v);
scanf("%d",&G[u][v]);
G[v][u]=G[u][v];
}
Dijkstra(st);
printf("%d %d\n",num[ed],w[ed]);
return 0;
}