PAT (Advanced Level) 1003 Emergency

橙三吉。 提交于 2020-03-04 16:02:58

题意

N个城市,每个城市有点权,M条带权无向边,从指定的起点城市到达指定的终点城市。要求路径最短,输出这样的最短路径有几条,其中路径上点权之和最大为多少。

思路

最短路,dijkstra。习惯性写堆优化的(自己搞一个结构体,重载一下小于号,代码可能更简洁一点)。因为还要求最短路径数量和路径最大点权和,所以稍微改一下算法:在更新距离不变时,更新答案;更新距离改变时,传递答案。

代码

#include <bits/stdc++.h>
using namespace std;
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	int n, m, st, en;
	cin >> n >> m >> st >> en;
	vector<int> num(n);
	for (int &e : num) cin >> e;
	vector<vector<pair<int, int>>> adj(n);
	for (int i = 0, u, v, val; i < m; ++i) {
		cin >> u >> v >> val;
		adj[u].emplace_back(v, val);
		adj[v].emplace_back(u, val);
	}
	vector<bool> vis(n, false);
	vector<int> dis(n, INT_MAX);
	dis[st] = 0;
	vector<int> way(n, 0);
	way[st] = 1;
	vector<int> sum(n, 0);
	sum[st] = num[st];
	priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
	q.push({0, st});
	while (!q.empty()) {
		int now, val;
		tie(val, now) = q.top();
		q.pop();
		vis[now] = true;
		for (auto e : adj[now]) {
			int to, nxt_dis;
			tie(to, nxt_dis) = e;
			if (vis[to]) continue;
			if (dis[to] > dis[now] + nxt_dis) {
				dis[to] = dis[now] + nxt_dis;
				q.push({dis[to], to});
				way[to] = way[now];
				sum[to] = sum[now] + num[to];
			}
			else if (dis[to] == dis[now] + nxt_dis) {
				way[to] += way[now];
				sum[to] = max(sum[to], sum[now] + num[to]);
			}
		}
	}
	cout << way[en] << ' ' << sum[en] << '\n';
	return 0;
} 

HINT

不定时更新更多题解,详见 git ! ! !

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!