求最短路(堆优化)

#include <bits/stdc++.h>
using namespace std;
#define LL long long
int main(){
	ios::sync_with_stdio(false);cin.tie(0);
	int n, m;
	cin >> n >> m;
	vector < vector <pair<LL, int> > > g(n + 1);
	for (int i = 1; i <= m; i ++ ){
		int u, v, w;
		cin >> u >> v >> w;
		g[u].push_back({w, v});
	}
	auto dijkstra = [&](){
		vector <LL> dis(n + 1, 1e9);
		vector <bool> vis(n + 1, false);
		dis[1] = 0;
		priority_queue < pair<int, int>, vector< pair<int, int> >, greater< pair<int, int> > > q;
		q.push({0, 1});
		while(q.size()){
			auto t = q.top();
			q.pop();
			int u = t.second;
			if (vis[u]) continue;
			vis[u] = true;
			for (auto [w, v] : g[u]){
				if (dis[v] > dis[u] + w){
					dis[v] = dis[u] + w;
					q.push({dis[v], v});
				}
			}
		}
		if (dis[n] == 1e9) cout << "-1\n";
		else cout << dis[n] << "\n";
	};
	dijkstra();
	return 0;
}

Acwing 模板:https://www.acwing.com/problem/content/852/

计算最短路的数量

题目链接

http://acm.zjgsu.edu.cn/contests/117/problems/0

题目大意:

输入 \(n, m, s, e\),分别表示点的数量、边的数量、起点和终点。点的编号从 0 开始,第二行输入每个点的快乐值(权重)。接下来 \(m\) 行每行输入三个数,\(u, v, w\),表示从 \(u\)\(v\) 有一条长为 \(w\) 的边。
输出从起点到终点的最短路的数量以及最短路的最大快乐值。

代码:

#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define fi first
#define se second
#define PLL pair <LL, LL>
#define pb push_back
const int N = 1e3 + 10;
LL s, e, n, m, dis[N], v[N], w[N], cnt[N], ans[N];
vector <PLL> g[N];
void dijkstra(){
	memset(dis, 0x3f, sizeof dis);
	dis[s] = 0;
	priority_queue< PLL, vector<PLL>, greater<PLL> > q;
	q.push( {0, s} );
	while ( q.size() ){
		PLL t = q.top();
		q.pop();
		LL x = t.se;
		if (v[x]) continue;
		v[x] = 1;
		for (auto tt : g[x]){
			LL d = tt.fi, y = tt.se;
			if (dis[y] > dis[x] + d){
				dis[y] = dis[x] + d;
				cnt[y] = cnt[x];
				ans[y] = ans[x] + w[y];
				q.push( {dis[y], y} );
			}
			else if (dis[y] == dis[x] + d){
				cnt[y] += cnt[x];
				ans[y] = max(ans[y], ans[x] + w[y]);
			}
		}
	}
}
int main(){
	cin >> n >> m >> s >> e;
	for (int i = 0; i < n; ++ i)
		scanf("%lld", &w[i]);
	for (int i = 1; i <= m; ++ i){
		LL a, b, c;
		scanf("%lld%lld%lld", &a, &b, &c);
		g[a].pb( {c, b} );
		g[b].pb( {c, a} );
	}
	cnt[s] = 1;
	ans[s] = w[s];
	dijkstra();
	cout << cnt[e] << " " << ans[e] << "\n";
	return 0;
}
posted on 2022-03-23 23:46  Hamine  阅读(35)  评论(0编辑  收藏  举报