#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXV = 510; // 最大顶点数
const int INF = 1000000000; // 无穷大
//顶点数,边数,起点,终点,邻接矩阵,点权
int V, E, start, end, G[MAXV][MAXV], weight[MAXV];
//最短距离,最大点权和,最短路径条数
int dist[MAXV], w[MAXV], num[MAXV];
//顶点i是否被访问
bool visit[MAXV] = {false};
void Dijkstra(int s){ // s为起点
fill(dist, dist + MAXV, INF);
memset(num, 0, sizeof(num));
memset(w, 0, sizeof(w));
dist[s] = 0;
w[s] = weight[s];
num[s] = 1;
for(int i = 0; i < V; i++){ // 循环V次
int u = -1, MIN = INF; // u使dist[u]最小,MIN存放最小的d[u]
for(int j = 0; j < V; j++){ // 找到未访问的顶点d[]最小
if(visit[j] == false && dist[j] < MIN){
u = j;
MIN = dist[j];
}
}
// 找不到小于INF的d[u],说明剩下的顶点和s不连通
if(u == -1) return;
visit[u] = true; // 标记u已被访问
for(int v = 0; v < V; v++){
// 如果v未被访问,且u能到达v,且以u为中介的点更优
if(visit[v] == false && G[u][v] != INF){
if(dist[u] + G[u][v] < dist[v]){ // 以u为中介点时能令d[v]更小
dist[v] = dist[u] + G[u][v]; // 覆盖d[v]
w[v] = w[u] + weight[v]; // 覆盖w[v]
num[v] = num[u]; // 覆盖num[v]
}else if(dist[u] + G[u][v] == dist[v]){ // 找到一条相同长度的路径
if(w[u] + weight[v] > w[v]){ // 以u为中介点时点权之和更大
w[v] = w[u] + weight[v]; // w[v]继承自w[u]
}
// 注意最短路径条数与点权无关,必须写在外面
num[v] += num[u];
}
}
}
}
}
int main(){
scanf("%d %d %d %d", &V, &E, &start, &end);
for(int i = 0; i < V; i++){ // 读入点权
scanf("%d", &weight[i]);
}
int a, b;
fill(G[0], G[0] + MAXV * MAXV, INF); // 初始化图
for(int i = 0; i < E; i++){
scanf("%d %d", &a, &b);
scanf("%d", &G[a][b]); // 读入边权
G[b][a] = G[a][b];
}
Dijkstra(start); // Dijkstra算法入口
printf("%d %d", num[end], w[end]); // 最短距离条数,最短路径中的最大点权
return 0;
}
PAT 甲级 A1003 (2019/02/24)
猜你喜欢
转载自www.cnblogs.com/zjsaipplp/p/10427564.html
今日推荐
周排行