您的位置:首页 > 其它

最短路算法Dijkstra

2014-02-24 08:47 169 查看
邻接矩阵,算法复杂度:O(V^2):

//input file
6 8
0 2 10
0 4 30
0 5 100
1 2 5
2 3 50
3 5 10
4 3 20
4 5 60


g中INF表示此边不存在

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <cstring>
int const MAXN = 1000, MAXM = MAXN*MAXN/2, INF = 0x3f3f3f3f;
int N = 6, M = 8;
int g[MAXN][MAXN], v[MAXN], d[MAXN], fa[MAXN];
void Dijkstra(int s)
{
memset(v, 0, sizeof(v));								//清空集合
memset(d, 0x3f, sizeof(d));
d[s] = 0;
for(int i = 0; i < N; i++)
{
int x, m = INF;
for(int y = 0; y < N; y++)							//找到集合外最小d[i]
if(!v[y] && d[y] <= m)
m = d[x=y];
v[x] = 1;
for(int y = 0; y < N; y++)							//更新从点x出发的距离
if(d[y] > d[x] + g[x][y])
{
d[y] = d[x] + g[x][y];
fa[y] = x;									//保存路径
}
}
}
int main()
{
freopen("in.txt", "r", stdin);

memset(g, 0x3f, sizeof(g));
scanf("%d%d", &N, &M);
for(int i = 0; i < M; i++)
{
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
g[u][v] = w;
}
Dijkstra(0);
printf("%d\n", d[N-1]);
return 0;
}


邻接表,优先队列  O(elg(v)):

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <functional>
using namespace std;
int const MAXN = 1000, MAXM = MAXN*MAXN/2, INF = 0x3f3f3f3f;
int N = 6, M = 8;
int fa[MAXN], v[MAXN], d[MAXN];
//邻接矩阵
int g[MAXN][MAXN];
int first[MAXN], nexte[MAXN]; //first[u]:保存结点u的第一条边的编号 next[e]:保存编号e的边的“下一条边”的编号

void Dijkstra(int s)
{
memset(v, 0, sizeof(v)); //清空集合
memset(d, 0x3f, sizeof(d));
d[s] = 0;
for(int i = 0; i < N; i++)
{
int x, m = INF;
for(int y = 0; y < N; y++) //找到集合外最小d[i]
if(!v[y] && d[y] <= m)
m = d[x=y];
v[x] = 1;
for(int y = 0; y < N; y++) //更新从点x出发的距离
if(d[y] > d[x] + g[x][y])
{
d[y] = d[x] + g[x][y];
fa[y] = x; //保存路径
}
}
}

//邻接表(链表实现)
struct Edge
{
int u, v, w;
}edge[MAXM];
typedef pair<int, int> pii;
priority_queue<pii, vector<pii>, greater<pii> > q;
int Dijkstra1(int s, int g)
{
memset(d, 0x3f, sizeof(d));
d[s] = 0;
q.push(make_pair(d[s], 0));
while(q.size())
{
pii u = q.top(); q.pop();
int x = u.second;
if(u.first > d[x]) continue;
for(int e = first[x]; e != -1; e = nexte[e])
{
int v = edge[e].v, u = edge[e].u, w = edge[e].w;
if(d[v] > d[x]+w)
{
d[v] = d[x]+w;
q.push(make_pair(d[v], v));
}
}
}
return d[g];
}

int main()
{
freopen("in.txt", "r", stdin);

memset(g, 0x3f, sizeof(g));
scanf("%d%d", &N, &M);

//初始化邻接表表头
for(int i = 0; i < N; i++) first[i] = -1;

for(int i = 0; i < M; i++)
{
int u, v, w;
//临接矩阵
scanf("%d%d%d", &u, &v, &w);
g[u][v] = w;
//临接表,插入链表
edge[i].u = u; edge[i].v = v; edge[i].w = w;
nexte[i] = first[u];
first[u] = i;
}
//Dijkstra(0);
//printf("%d\n", d[N-1]);
int ans = Dijkstra1(0, N-1);
printf("%d\n", ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息