#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<stack>
#include<vector>
#include<map>
#include<unordered_map>
using namespace std;
/*
题意:尽可能快的到达目的地并且尽可能找到更多的帮手
N(点数)M(边) c1 c2
最短距离条数 最多可能聚集的队数(如果最多)
分析:使用dijkstra算法,图的点权是救援小组个数,需要求出最短路径中
最大的点权和。
1.更新d时,也需要更新num[v] = num[u],w[v]
2.如果相等时 需要更新num[v]+=num[u],并且看情况是否更新w
*/
int n, m, c1, c2;
int g[510][510], w[510], d[510], weight[510], num[510];
bool vis[510];
const int inf = 0x3fffffff;
int main() {
cin >> n >> m >> c1 >> c2;
for (int i = 0; i < n; ++i) scanf("%d", &weight[i]);
fill(g[0], g[0] + 510 * 510, inf);
fill(d, d + 510, inf);
int a, b, c;
for (int i = 0; i < m; ++i) {
scanf("%d %d %d", &a, &b, &c);
g[a][b] = g[b][a] = c;
}
d[c1] = 0;
w[c1] = weight[c1];
num[c1] = 1;
for (int i = 0; i < n; ++i) {
int u = -1, minn = inf;
for (int j = 0; j < n; ++j) {
if (vis[j] == false && d[j] < minn) {
u = j;
minn = d[j];
}
}
if (u == -1)break;
vis[u] = true;
for (int v = 0; v < n; ++v) {
if (d[v] > d[u] + g[u][v]) {
num[v] = num[u];
d[v] = d[u] + g[u][v];
w[v] = w[u] + weight[v];
}
else if (d[v] == d[u] + g[u][v]) {
num[v] += num[u];
if (w[v] < weight[v] + w[u]) w[v] = weight[v] + w[u];
}
}
}
cout << num[c2] << " "<<w[c2];
return 0;
}
A1003
最新推荐文章于 2022-08-16 15:40:48 发布