c++ spfa 鏈式前向星版本加上SLF優化版本的實現

普通版本

#include <iostream>
#include <queue>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <limits.h>
const int INF = 0x3f3f3f3f;
const int MAXN = 100010;
const int MAXM = 500050;
using namespace std;
struct Edge {
	int to, next, w;
	Edge(const int & _to = int(), const int & _next = int(), const int & _w = int()) : to(_to), next(_next), w(_w) {}
} edge[MAXM];
int dist[MAXN];
int visit[MAXN];
int head[MAXN];
int cnt;
void spfa(const int & st) {
	dist[st] = 0;
	queue<int> q;
	q.push(st);
	visit[st] = 1;
	while (!q.empty()) {
		int x = q.front();
		q.pop();
		visit[x] = 0;
		for (int i = head[x]; i;i = edge[i].next) {
			int y = edge[i].to;
			if (dist[y] > dist[x] + edge[i].w) {
				dist[y] = dist[x] + edge[i].w;
				if (!visit[y]) {
					q.push(y);
					visit[y] = 1;
				}
			}
		}
	}
}
inline void addEdge(const int & u, const int & v, const int & w) {
	++cnt;
	edge[cnt].to = v;
	edge[cnt].next = head[u];
	edge[cnt].w = w;
	head[u] = cnt;
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	int n, m, s;
	cin >> n >> m >> s;
	memset(dist, INF, sizeof(dist));
	for (register int i = 1; i <= m; ++i) {
		register int u, v, w;
		cin >> u >> v >> w;
		addEdge(u, v, w);
	}
	spfa(s);
	for (int i = 1; i <= n; ++i) {
		if (dist[i] >= INF) {
			cout << INT_MAX << ' ';
		}
		else {
			cout << dist[i] << ' ';
		}
	}
	return 0;
}

SLF優化(雙端隊列優化版本)

#include <iostream>
#include <queue>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <limits.h>
const int INF = 0x3f3f3f3f;
const int MAXN = 100010;
const int MAXM = 500050;
using namespace std;
struct Edge {
	int to, next, w;
	Edge(const int & _to = int(), const int & _next = int(), const int & _w = int()) : to(_to), next(_next), w(_w) {}
} edge[MAXM];
int dist[MAXN];
int visit[MAXN];
int head[MAXN];
int cnt;
void spfa(const int & st) {
	dist[st] = 0;
	deque<int> q;
	q.push_back(st);
	visit[st] = 1;
	while (!q.empty()) {
		int x = q.front();
		q.pop_front();
		visit[x] = 0;
		for (int i = head[x]; i;i = edge[i].next) {
			int y = edge[i].to;
			if (dist[y] > dist[x] + edge[i].w) {
				dist[y] = dist[x] + edge[i].w;
				if (!visit[y]) {
					if (!q.empty() && dist[y] < dist[q.front()]) {
						q.push_front(y);
					}
					else {
						q.push_back(y);
					}
					visit[y] = 1;
				}
			}
		}
	}
}
inline void addEdge(const int & u, const int & v, const int & w) {
	++cnt;
	edge[cnt].to = v;
	edge[cnt].next = head[u];
	edge[cnt].w = w;
	head[u] = cnt;
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	int n, m, s;
	cin >> n >> m >> s;
	memset(dist, INF, sizeof(dist));
	for (register int i = 1; i <= m; ++i) {
		register int u, v, w;
		cin >> u >> v >> w;
		addEdge(u, v, w);
	}
	spfa(s);
	for (int i = 1; i <= n; ++i) {
		if (dist[i] >= INF) {
			cout << INT_MAX << ' ';
		}
		else {
			cout << dist[i] << ' ';
		}
	}
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章