随笔 - 216,  文章 - 0,  评论 - 17,  阅读 - 25450

求最短路(堆优化)

#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,表示从 uv 有一条长为 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   Hamine  阅读(49)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示