#include<iostream> #include<cstring> #include<algorithm> #include<vector> using namespace std; int g[510][510]; int num[510]; int dist[510]; int st[510]; //st确定的顺序不一定是最短路径的顺序,二者没关系 int value[510];//到每个点最短路救援队伍的数量 int cnt[510];//到每个点最短路的数目 int pre[510];//父节点 int main() { int n, m, s, d; cin >> n >> m >> s >> d; memset(dist, 0x3f, sizeof dist); memset(g, 0x3f, sizeof g); memset(pre, -1, sizeof pre); for (int i = 0; i < n; i++) { cin >> num[i]; } for (int i = 0; i < m; i++) { int c1, c2, w; cin >> c1 >> c2 >> w; g[c1][c2] = w; g[c2][c1] = w; } dist[s] = 0; int t = -1; value[s] = num[s]; cnt[s] = 1; // st[s] = 1; for (int j = 0; j < n; j++) { int tmp = 0; t = -1; for (int i = 0; i < n; i++) { if (!st[i] && (t == -1 || dist[i] < t)) { t = dist[i]; tmp = i; } } st[tmp] = 1; for (int i = 0; i < n; i++) { if (dist[i] > dist[tmp] + g[tmp][i]) {//如果有更短路径 dist[i] = dist[tmp] + g[tmp][i]; value[i] = value[tmp] + num[i]; pre[i] = tmp; cnt[i] = cnt[tmp]; } else if ((dist[i] == dist[tmp] + g[tmp][i]) && (tmp != i)) {//如果与最短路长度相等 cnt[i] += cnt[tmp]; if (value[i] < value[tmp] + num[i]) { value[i] = value[tmp] + num[i]; pre[i] = tmp; } } } } cout << cnt[d] << ' ' << value[d] << endl; vector<int> path; path.push_back(d); while (pre[d] != -1) { path.push_back(pre[d]); d = pre[d]; } reverse(path.begin(), path.end()); for (auto iter = path.begin(); iter != path.end() - 1; iter++) cout << *iter << ' '; cout << path.back(); } /*本题出现的问题 1.数组初始化,g[][]起初没有初始化,应该初始化两点距离距离为正无穷 2.无向图要存两个方向的边 3.cnt[i] += cnt[tmp]; 思路要明晰,不是加一是把到tmp的最短路数都加上 4.if elseif 使用时一定注意第二个用if 还是 else if 5.总体逻辑要理清,模板题 */
标签:tmp,pre,dist,救援,int,value,001,L2,510 From: https://www.cnblogs.com/youngbrooke/p/17224027.html