CDOJ 30 最短路 解题报告

啊啊啊打博文真是累的要死……

题目链接:http://acm.uestc.edu.cn/#/problem/show/30

题目就是标算,不解释了,用的是Bellman Ford算法,的队列优化版SPFA

我不太喜欢用C++的STL,所以用的都是自己手打的队列。优先队列打着太麻烦所以就不用Dijkstra了……人懒没救

随便一提,用的是一行广搜,的扩展版(所以说Bellman Ford算法不就是广搜吗),虽然不是一行了,不过SPFA算法也简单多了。我在后面的一道题会讲一讲一行广搜……嗯,树上战争。

我这个人怎么这么喜欢压代码……

#include <cstdio>
#include <cstring>
using namespace std;

const int MAXN = 105;
const int MAXM = 20005;

int N, M;
int g[MAXN], to[MAXM], next[MAXM], w[MAXM], e;
int dis[MAXN], queue[MAXN], head, tail;
bool inq[MAXN];

int nextInt() {
	char c; while ((c = getchar()) < '0' || c > '9'); int r = c - '0';
	while ((c = getchar()) >= '0' && c <= '9') (r *= 10) += c - '0';
	return r;
}

void addEdge(int u, int v, int len) {
	next[e] = g[u]; g[u] = e; to[e] = v; w[e++] = len;
}

int Bellman_Ford(int s, int t) {
	memset(dis, 0x7f, sizeof dis); dis[s] = 0;
	memset(inq, false, sizeof inq);
	for (inq[queue[head = tail = 0] = s] = true; head <= tail; inq[queue[head++ % N]] = false)
		for (int u = queue[head % N], e = g[u], v = to[e]; ~e; v = to[e = next[e]])
			if (dis[v] > dis[u] + w[e]) {
				dis[v] = dis[u] + w[e];
				if (!inq[v]) inq[queue[++tail % N] = v] = true;
			}
	return dis[t];
}

int main() {
	while ((N = nextInt()) && (M = nextInt())) {
		memset(g, -1, sizeof g); e = 0;
		for (int i = 0; i < M; ++i) {
			int A = nextInt(), B = nextInt(), C = nextInt();
			addEdge(A, B, C); addEdge(B, A, C);
		}
		printf("%d
", Bellman_Ford(1, N));
	}
	return 0;
}
原文地址:https://www.cnblogs.com/johnsonyip/p/5668744.html