• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
jacklee404
Never Stop!
博客园    首页    新随笔    联系   管理    订阅  订阅
选择最佳路线

选择最佳路线

题目

选择最佳路线

思路

​ 比较简单的题,可以建立虚拟源点或者建立反向边,都是比较简单的思路,这里直接上各种思路的代码

Code

Dijkstra建立反向边

#include <iostream>
#include <cstring>
#include <queue>

using i64 = long long;

const int N = 1e3 + 10, M = 2e4 + 1010;

int n, m, s;

int h[N], e[M], w[M], ne[M], idx;

int dist[N];

bool st[N];

void add(int a, int b, int c) {
	ne[idx] = h[a], h[a] = idx, e[idx] = b, w[idx ++] = c;
}

void dijkstra(int s) {
	memset(dist, 0x3f, sizeof dist);
	memset(st, false, sizeof st);

	std::priority_queue<std::pair<int, int>> h1;

	dist[s] = 0;

	h1.push({0, s});

	while (h1.size()) {
		auto t = h1.top(); h1.pop();

		int u = t.second;

		if (st[u]) continue;

		st[u] = true;

		// std::cout << u << "\n";

		for (int i = h[u]; ~i; i = ne[i]) {
			int j = e[i];

			if (dist[j] > dist[u] + w[i]) {
				dist[j] = dist[u] + w[i];
				h1.push({-dist[j], j});
			}
		}
	}
}

int main() {	
	while (std::cin >> n >> m >> s) {
		memset(h, -1, sizeof h);
		idx = 0;
		
		for (int i = 1; i <= m; i ++) {
			int p, q, t;

			std::cin >> p >> q >> t;

			add(q, p, t);
		}

		dijkstra(s);

		int t;

		std::cin >> t;

		int res = 0x3f3f3f3f;

		for (int i = 1; i <= t; i ++) {
			int k;
			std::cin >> k;

			res = std::min(res, dist[k]);
		}

		if (res == 0x3f3f3f3f) res = -1;

		std::cout << res << "\n";
	}
}

SPFA建立反向边

#include <iostream>
#include <cstring>
#include <queue>

using i64 = long long;

const int N = 1e3 + 10, M = 2e4 + 1010;

int n, m, s;

int h[N], e[M], w[M], ne[M], idx;

int dist[N];

bool st[N];

void add(int a, int b, int c) {
	ne[idx] = h[a], h[a] = idx, e[idx] = b, w[idx ++] = c;
}

void spfa(int s) {
	memset(dist, 0x3f, sizeof dist);
	memset(st, false, sizeof st);

	std::queue<int> q1;

	q1.push(s);
	
	dist[s] = 0;

	while (q1.size()) {
		int t = q1.front(); q1.pop();

		st[t] = false;

		for (int i = h[t]; ~i; i = ne[i]) {
			int j = e[i];
			if (dist[j] > dist[t] + w[i]) {
				dist[j] = dist[t] + w[i];
				
				if (!st[j]) {
					q1.push(j);
					st[j] = true;
				}
			}
		}
	}
}

int main() {	
	while (std::cin >> n >> m >> s) {
		memset(h, -1, sizeof h);
		idx = 0;
		
		for (int i = 1; i <= m; i ++) {
			int p, q, t;

			std::cin >> p >> q >> t;

			add(q, p, t);
		}

		spfa(s);

		int t;

		std::cin >> t;

		int res = 0x3f3f3f3f;

		for (int i = 1; i <= t; i ++) {
			int k;
			std::cin >> k;

			res = std::min(res, dist[k]);
		}

		if (res == 0x3f3f3f3f) res = -1;

		std::cout << res << "\n";
	}
}

Dijkstra建立虚拟源点

#include <iostream>
#include <cstring>
#include <queue>

using i64 = long long;

const int N = 1e3 + 10, M = 2e4 + 1010;

int n, m, s;

int h[N], e[M], w[M], ne[M], idx;

int dist[N];

bool st[N];

void add(int a, int b, int c) {
	ne[idx] = h[a], h[a] = idx, e[idx] = b, w[idx ++] = c;
}

void dijkstra(int s) {
	memset(dist, 0x3f, sizeof dist);
	memset(st, false, sizeof st);

	std::priority_queue<std::pair<int, int>> h1;

	dist[s] = 0;

	h1.push({0, s});

	while (h1.size()) {
		auto t = h1.top(); h1.pop();

		int u = t.second;

		if (st[u]) continue;

		st[u] = true;

		for (int i = h[u]; ~i; i = ne[i]) {
			int v = e[i];

			if (dist[v] > dist[u] + w[i]) {
				dist[v] = dist[u] + w[i];
				h1.push({-dist[v], v});
			}
		}
	}
}

int main() {	
	while (std::cin >> n >> m >> s) {
		memset(h, -1, sizeof h);
		idx = 0;
		
		for (int i = 1; i <= m; i ++) {
			int p, q, t;

			std::cin >> p >> q >> t;

			add(p, q, t);
		}

		int w;

		std::cin >> w;

		for (int i = 1; i <= w; i ++) {
			int k;
			std::cin >> k;

			add(0, k, 0);
		}

		dijkstra(0);

		if (dist[s] == 0x3f3f3f3f) std::cout << -1 << "\n";
		else std::cout << dist[s] << "\n";
	}
}

SPFA建立虚拟源点

#include <iostream>
#include <cstring>
#include <queue>

using i64 = long long;

const int N = 1e3 + 10, M = 2e4 + 1010;

int n, m, s;

int h[N], e[M], w[M], ne[M], idx;

int dist[N];

bool st[N];

void add(int a, int b, int c) {
	ne[idx] = h[a], h[a] = idx, e[idx] = b, w[idx ++] = c;
}

void spfa(int s) {
	memset(dist, 0x3f, sizeof dist);
	memset(st, false, sizeof st);

	std::queue<int> q1;

	q1.push(s);
	
	dist[s] = 0;

	while (q1.size()) {
		int t = q1.front(); q1.pop();

		st[t] = false;

		for (int i = h[t]; ~i; i = ne[i]) {
			int j = e[i];
			if (dist[j] > dist[t] + w[i]) {
				dist[j] = dist[t] + w[i];
				if (!st[j]) {
					q1.push(j);
					st[j] = true;
				}
			}
		}
	}
}

int main() {	
	while (std::cin >> n >> m >> s) {
		memset(h, -1, sizeof h);
		idx = 0;
		
		for (int i = 1; i <= m; i ++) {
			int p, q, t;

			std::cin >> p >> q >> t;

			add(p, q, t);
		}

		int w;

		std::cin >> w;

		for (int i = 1; i <= w; i ++) {
			int k;
			std::cin >> k;

			add(0, k, 0);
		}

		spfa(0);

		if (dist[s] == 0x3f3f3f3f) std::cout << -1 << "\n";
		else std::cout << dist[s] << "\n";
	}
}
posted on 2023-04-13 11:28  Jack404  阅读(17)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3