# poj 2449Remmarguts' Date uvaoj 10740 not the best dijkstra或spfa或bellman-ford k短路 A*

``````struct Edge {
int to, w, next;
}edge[M];``````

``````void addEdge(int u, int v, int w)
{
edge[ecnt].to = v;
edge[ecnt].w = w;
}``````

a. Dijkstra算法
dijkstra适用于边权为正的情况，在边权为负的情况下，不能正确求出最短路。算法同时适用于有向图和无向图。下边是伪代码：

``````清除所有点的标号

``````void dijkstra(int start)
{
clr(vis, 0);
for (int i = 1; i <= n; ++i) {
dist[i] = INF;
}
dist[start] = 0;
for (int i = 1; i <= n; ++i) {
int x = 0;
int mnx = INF;
for (int j = 1; j <= n; ++j) {
if (!vis[j] && mnx >= dist[j]) {    // 保证可以选一个点
x = j;
mnx = dist[j];
}
}
vis[x] = true;
while (p >= 0) {
int v = redge[p].to;
int w = redge[p].value;
dist[v] = min(dist[x] + w, dist[v]);
p = redge[p].next;
}
}
}``````

``````void heap_dijkstra(int start)
{
clr(vis, 0);
for (int i = 1; i <= n; ++i) {
dist[i] = INF;
}
dist[start] = 0;
priority_queue<Node> pq;
pq.push(Node(start, 0, 0));
while (!pq.empty()) {
Node x = pq.top();
pq.pop();
if (vis[x.u]) {//松弛过就不再松弛了
continue;
}
vis[x.u] = true;
while (p >= 0) {
int a = redge[p].from;
int b = redge[p].to;
int w = redge[p].value;
if (dist[b] > dist[a] + w) {
dist[b] = dist[a] + w;
pq.push(Node(b, dist[b], 0));
}
p = redge[p].next;
}
}
}``````

b. Bellman-ford算法
dijkstra不能处理带有负权的图，需要注意，当负权存在时，连最短路都不一定存在了，但是还是有办法在最短路存在的情况下把它求出来。如果最短路存在，一定存在一个不含环的最短路。既然不含环，最短路最多只经过n-1个结点（不含起点），可以通过n-1轮松弛操作得到。代码如下：

``````void bellman_ford(int start)
{
for (int i = 1; i <= n; ++i) {
dist[i] = INF;
}
dist[start] = 0;
for (int i = 0; i < n - 1; ++i) {//松弛n-1次
for (int j = 0; j < m; ++j) {//每次对m条边松弛
int u = redge[j].from;
int v = redge[j].to;
if (dist[u] < INF) {
dist[v] = min(dist[v], dist[u] + redge[j].value);
}
}
}
}``````

``````void spfa(int start)
{
for (int i = 1; i <= n; ++i) {
dist[i] = INF;
}
dist[start] = 0;
clr(c, 0);
clr(vis, 0);
queue<int> q;
q.push(start);
vis[start] = true;
while (!q.empty()) {
int x = q.front();
q.pop();
vis[x] = false;;
while (p >= 0) {
int u = redge[p].from;
int v = redge[p].to;
int w = redge[p].value;
if (dist[u] + w < dist[v]) {
dist[v] = dist[u] + w;
if (!vis[v]) {
vis[v] = true;
++c[v];
if (c[v] >= n) {
return;
}
q.push(v);
}
}
p = redge[p].next;
}
}
}``````

``````int bfs(void)
{
priority_queue<Node> pq;
pq.push(Node(s, 0, dist[s]));
if (dist[s] == INF) {   // 不可达
return -1;
}
int cnt = 0;
while (!pq.empty()) {
Node u = pq.top();
pq.pop();
if (u.u == t) {
++cnt;
}
if (u.u == t && cnt == k) {
return u.g;
}
while (p >= 0) {
pq.push(Node(edge[p].to, u.g + edge[p].value, dist[edge[p].to]));
p = edge[p].next;
}
}
return -1;
}``````

``````/************************************************************************* > File Name: 2449.cpp > Author: gwq > Mail: gwq5210@qq.com > Created Time: 2015年08月28日 星期五 09时53分34秒 ************************************************************************/

#include <cmath>
#include <ctime>
#include <cctype>
#include <climits>
#include <cstdio>
#include <cstdlib>
#include <cstring>

#include <map>
#include <set>
#include <queue>
#include <stack>
#include <string>
#include <vector>
#include <sstream>
#include <iostream>
#include <algorithm>

#define INF (INT_MAX / 10)
#define clr(arr, val) memset(arr, val, sizeof(arr))
#define pb push_back
#define sz(a) ((int)(a).size())

using namespace std;
typedef set<int> si;
typedef vector<int> vi;
typedef map<int, int> mii;
typedef pair<int, int> pii;
typedef long long ll;

const double esp = 1e-5;

#define N 1010
#define M 100010

int n, m, s, t, k;
bool vis[N];

struct Edge {
int from, to, value, next;
}edge[M], redge[M];

struct Node {
int u, g, h;
Node() {}
Node(int uu, int gg, int hh): u(uu), g(gg), h(hh) {}
};

bool operator <(Node u, Node v)
{
return u.g + u.h > v.g + v.h;
}

void addEdge(int u, int v, int x)
{
edge[ecnt].from = u;
edge[ecnt].to = v;
edge[ecnt].value = x;
}

void addREdge(int u, int v, int x)
{
redge[recnt].from = u;
redge[recnt].to = v;
redge[recnt].value = x;
}

void dijkstra(int start)
{
clr(vis, 0);
for (int i = 1; i <= n; ++i) {
dist[i] = INF;
}
dist[start] = 0;
for (int i = 1; i <= n; ++i) {
int x = 0;
int mnx = INF;
for (int j = 1; j <= n; ++j) {
if (!vis[j] && mnx >= dist[j]) {    // 保证可以选一个点
x = j;
mnx = dist[j];
}
}
vis[x] = true;
while (p >= 0) {
int v = redge[p].to;
int w = redge[p].value;
dist[v] = min(dist[x] + w, dist[v]);
p = redge[p].next;
}
}
}

void heap_dijkstra(int start)
{
clr(vis, 0);
for (int i = 1; i <= n; ++i) {
dist[i] = INF;
}
dist[start] = 0;
priority_queue<Node> pq;
pq.push(Node(start, 0, 0));
while (!pq.empty()) {
Node x = pq.top();
pq.pop();
if (vis[x.u]) {
continue;
}
vis[x.u] = true;
while (p >= 0) {
int a = redge[p].from;
int b = redge[p].to;
int w = redge[p].value;
if (dist[b] > dist[a] + w) {
dist[b] = dist[a] + w;
pq.push(Node(b, dist[b], 0));
}
p = redge[p].next;
}
}
}

void bellman_ford(int start)
{
for (int i = 1; i <= n; ++i) {
dist[i] = INF;
}
dist[start] = 0;
for (int i = 0; i < n - 1; ++i) {
for (int j = 0; j < m; ++j) {
int u = redge[j].from;
int v = redge[j].to;
if (dist[u] < INF) {
dist[v] = min(dist[v], dist[u] + redge[j].value);
}
}
}
}

void spfa(int start)
{
for (int i = 1; i <= n; ++i) {
dist[i] = INF;
}
dist[start] = 0;
clr(c, 0);
clr(vis, 0);
queue<int> q;
q.push(start);
vis[start] = true;
while (!q.empty()) {
int x = q.front();
q.pop();
vis[x] = false;;
while (p >= 0) {
int u = redge[p].from;
int v = redge[p].to;
int w = redge[p].value;
if (dist[u] + w < dist[v]) {
dist[v] = dist[u] + w;
if (!vis[v]) {
vis[v] = true;
++c[v];
if (c[v] >= n) {
return;
}
q.push(v);
}
}
p = redge[p].next;
}
}
}

int bfs(void)
{
priority_queue<Node> pq;
pq.push(Node(s, 0, dist[s]));
if (dist[s] == INF) {   // 不可达
return -1;
}
int cnt = 0;
while (!pq.empty()) {
Node u = pq.top();
pq.pop();
if (u.u == t) {
++cnt;
}
if (u.u == t && cnt == k) {
return u.g;
}
while (p >= 0) {
pq.push(Node(edge[p].to, u.g + edge[p].value, dist[edge[p].to]));
p = edge[p].next;
}
}
return -1;
}

int main(int argc, char *argv[])
{
while (scanf("%d%d", &n, &m) != EOF) {
int u, v, x;
ecnt = 0;
recnt = 0;
for (int i = 0; i < m; ++i) {
scanf("%d%d%d", &u, &v, &x);
}
scanf("%d%d%d", &s, &t, &k);
if (s == t) {
++k;
}
//dijkstra(t);
//bellman_ford(t);
//spfa(t);
heap_dijkstra(t);
printf("%d\n", bfs());
}
return 0;
}``````
原文作者：Bellman - ford算法
原文地址: https://blog.csdn.net/gwq5210/article/details/48091923
本文转自网络文章，转载此文章仅为分享知识，如有侵权，请联系博主进行删除。