# 基础最短路算法【渣】

119 篇文章 0 订阅
34 篇文章 0 订阅

1. bellman-ford
2. dijkstra
3. floyd
4. spfa(bellman-ford+queue)
5. dijkstra+heap(priority_queue)

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<string>
#include<vector>
#include<queue>
#include<map>
#include<algorithm>
using namespace std;
inline int Rint() { int x; scanf("%d", &x); return x; }
#define FOR(i, a, b) for(int i=(a); i<=(b); i++)
#define FORD(i,a,b) for(int i=(a);i>=(b);i--)
#define REP(x) for(int i=0; i<(x); i++)
typedef long long int64;
#define INF (1<<30)
const double eps = 1e-8;
#define bug(s) cout<<#s<<"="<<s<<" "

#define MAXN 102
#define MAXM 10002
struct node
{
int u, v, w;
} edge[MAXM];
int idx;
int n, m;
void init() {
idx = 0;
}
void addedge(int u, int v, int w) {
edge[idx].u = u; edge[idx].v = v; edge[idx].w = w;
}

int dist[MAXN];

// bellman_ford，O(nm)
void bellman_ford(int st) {
REP(n)
dist[i] = i==st? 0 : INF;
FOR(k, 1, n-1) {
FOR(e, 0, idx-1) {
int u = edge[e].u, v = edge[e].v;
dist[v] = min(dist[v], dist[u]+edge[e].w);
}
}
}

// dijkstra，O(n^2)
int ins[MAXN];
void dijkstra(int st) {
memset(ins, 0, sizeof(ins));
REP(n) dist[i] = i==st? 0 : INF;
REP(n) {
int u=-1;
FOR(j, 0, n-1) if(!ins[j]) {
if(u==-1) u=j;
u = dist[u]>dist[j]? j : u;
}
ins[u] = 1;
int v = edge[e].v;
dist[v] = min(dist[v], dist[u]+edge[e].w);
}
}
}

// floyd，点对，O(n^3)
int dis[MAXN][MAXN];
FOR(i, 0, n-1)
FOR(j, 0, n-1) {
dis[i][j] = INF>>1;
}
REP(m) {
int u = Rint();
int v = Rint();
int w = Rint();
u--, v--;
dis[u][v] = min(dis[u][v], w);
dis[v][u] = dis[u][v];
}
}
void floyd() {
FOR(k, 0, n-1)
FOR(i, 0, n-1)
FOR(j, 0, n-1) {
dis[i][j] = min(dis[i][j], dis[i][k]+dis[k][j]);
}
}

// spfa (bellman-ford + queue)，O(km)，k~=2
int que[MAXN], front, tail;
int inq[MAXN];
void spfa(int st) {
front = tail = 0;
memset(inq, 0, sizeof(inq));
REP(n) dist[i] = i==st? 0 : INF;
que[(tail++)%MAXN] = st;
inq[st] = 1;
while(front%MAXN != tail%MAXN) {
int u = que[(front++)%MAXN];
inq[u] = 0;
int v = edge[e].v;
if(dist[v]>dist[u]+edge[e].w) {
dist[v] = dist[u]+edge[e].w;
if(!inq[v]) {	// 加了这个，才能保证queue里不超过n个点
que[(tail++)%MAXN] = v;
inq[v] = 1;
}
}
}
}
}

// dijkstra + heap（STL,priority_queue），O(nlogn)
typedef pair<int,int> pii;
#define mp(a,b) make_pair((a),(b))
priority_queue<pii, vector<pii>, greater<pii> > q;
/*
priority_queue 对于基本类型的使用方法相对简单。他的模板声明带有三个参数:
priority_queue<Type, Container, Functional>

Container 必须是用数组实现的容器，比如 vector, deque 但不能用 list.
STL里面默认用的是 vector. 比较方式默认用 operator< ,

*/
void dijkstra_heap(int st) {
memset(ins, 0, sizeof(ins));
REP(n) dist[i] = i==st? 0 : INF;
q.push(mp(dist[st], st));
while(!q.empty()) {
pii p = q.top(); q.pop();
int u = p.second;
if(ins[u]) continue;
ins[u] = 1;
int v = edge[e].v;
if(dist[v]>dist[u]+edge[e].w) {
dist[v] = dist[u]+edge[e].w;
q.push(mp(dist[v], v));
}
}
}
}

// HDOJ 2544
int main() {
while(scanf("%d%d", &n, &m)!=-1 && (n+m)) {
init();
REP(m) {
int u = Rint();
int v = Rint();
int w = Rint();
u--, v--;
}
// bellman_ford(0);
// dijkstra(0);
// spfa(0);
dijkstra_heap(0);
printf("%d\n", dist[n-1]);

// floyd();
// printf("%d\n", dis[0][n-1]);
}
}

• 1
点赞
• 0
收藏
觉得还不错? 一键收藏
• 打赏
• 0
评论
01-24 2593
06-12 1万+
11-28 86
11-16 1435
08-21 9156
08-07 6298
08-05 2800

### “相关推荐”对你有帮助么？

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

¥1 ¥2 ¥4 ¥6 ¥10 ¥20

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、付费专栏及课程。