求最短路径及其条数,顺便求同样的最短路径上的最大的点权和。
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXV = 510;
const int INF = 100000000;
int d[MAXV], G[MAXV][MAXV], w[MAXV], num[MAXV],weight[MAXV];
int n, m, st, ed;
bool vis[MAXV];
void Dij(int s){
fill(vis, vis + MAXV, false);
fill(d, d + MAXV, INF);
fill(num, num + MAXV, 0);
fill(w, w + MAXV, 0);
//memset(num, 0, sizeof(num));
//memset(w, 0, sizeof(w));
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] && 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] && G[u][v] != INF){
if (d[u] + G[u][v] < d[v]){
d[v] = d[u] + G[u][v];
num[v] = num[u];
w[v] = w[u] + weight[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];
}
}
}
}
}
int main(){
fill(G[0], G[0] + MAXV*MAXV, INF);
fill(weight, weight + MAXV, 0);
scanf("%d%d%d%d", &n, &m, &st, &ed);
for (int i = 0; i < n; i++){
scanf("%d", &weight[i]);
}
int u, v;
for (int i = 0; i < m; i++){
scanf("%d%d", &u, &v);
scanf("%d", &G[u][v]);
G[v][u] = G[u][v];
}
Dij(st);
printf("%d %d", num[ed], w[ed]);
return 0;
}