最近正好在学最短路径,借此机会把学到的知识总结下,一来分享给大家阅读,二来方便以后自己查阅。
先列一下下面会总结到的求最短路径的算法:
1.Dijkstra算法;
2.Bellman-Ford算法;
3.Folyd算法;
4.SPFA算法;
Dijkstra算法:求单源最短路径(不带负权重的环)
step2.从V-U中选择使dis[i]值最小的顶点i,将i加入到U中;
step3.更新与i直接相邻顶点的dis值(dis[j]=min{dis[j],dis[i]+cost[i][j]})。
step4.重复step2和step3,直到U=V,停止。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
#define MAXN 10000
const int INF=0x3f3f3f3f;
int n, m, ori;
int dis[MAXN], pre[MAXN];
int cost[MAXN][MAXN];
struct node
{
int v;
int len;
node(){}
node(int vv, int ll):v(vv), len(ll){}
bool operator < (const node& a) const
{
return len > a.len;
}
};
void Dijkstra()
{
for(int i = 1; i <= n; i++)
dis[i] = INF;
priority_queue<node> q;//最小优先队列优化
q.push(node(ori, 0));
dis[ori] = 0;
while(!q.empty())
{
node t;
t = q.top();
q.pop();
int now = t.v;
for(int j = 1; j <= n; j++)
{
if(cost[now][j] != INF && dis[j] > dis[now] + cost[now][j])
{
dis[j] = dis[now] + cost[now][j];
pre[j] = now;
q.push(node(j, dis[j]));
}
}
}
}
void print_path(int pos)
{
printf("%d\n", dis[pos]);
while(ori != pos)
{
printf("%d<---", pos);
pos = pre[pos];
}
printf("%d\n", ori);
}
int main()
{
scanf("%d%d%d", &n, &m, &ori);
int u, v, w;
memset(cost, INF, sizeof(cost));
while(m--)
{
scanf("%d%d%d", &u, &v, &w);
cost[u][v] = w;
cost[v][u] = w;//若是有向图则不要这行
}
Dijkstra();
for(int i = 1; i <= n; i++)
{
printf("%d to %d: ", ori, i);