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\n", Bellman_Ford(1, N));
}
return 0;
}