题目链接
题目分析:
输入结点信息,求最短路径;路径多条时,根据点的权重,输出路径中点的累加权重最大的那条
解题思路:
在原有Dijkstra()
算法的基础上,新增数组w[]
,记录从起点到某点的累计点权,
当路径长度相同时,更新为权重更大的即可
/**********************************
*@ID: 3stone
*@ACM: PAT.A1003 Emergency
*@Time: 18/8/20
*@IDE: VSCode 2018 + clang++
***********************************/
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 505;
const int INF = 1000000000;
int G[maxn][maxn]; //图
int d[maxn]; //起点到此点的距离
int vis[maxn]; //标记是否访问
int weight[maxn]; //点的权重
int w[maxn]; //到每个点的最短路径的累计权重
int num[maxn]; //到每个点的最短路径条数
int N, M, C1, C2;
void Dijkstra(int s) {
d[s] = 0;
num[s] = 1;
w[s] = weight[s];
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[u] + G[u][v] < d[v]) {
d[v] = d[u] + G[u][v];
w[v] = w[u] + weight[v];
num[v] = num[u];
} else if (d[u] + G[u][v] == d[v]) {
num[v] += num[u];
if(w[u] + weight[v] > w[v]) //当路径长度相同时,只需记录较大的权重即可,因为最后只需输出权重
w[v] = w[u] + weight[v];
}
}//if
}//for - v
}//for - i
}//Dijkstra
int main() {
int c1, c2, L;
while(scanf("%d%d%d%d", &N, &M, &C1, &C2) != EOF) {
fill(d, d + maxn, INF);
memset(vis, false, sizeof(vis));
fill(G[0], G[0] + maxn * maxn, INF);
//输入结点权重
for(int i = 0; i < N; i++) {
scanf("%d", &weight[i]);
}
//输入边信息
for(int i = 0; i < M; i++) {
scanf("%d%d%d", &c1, &c2, &L);
G[c1][c2] = L;
G[c2][c1] = L;
}
Dijkstra(C1);
printf("%d %d\n", num[C2], w[C2]);
}
return 0;
}