最短路算法Dijkstra
2014-02-24 08:47
169 查看
邻接矩阵,算法复杂度:O(V^2):
g中INF表示此边不存在
邻接表,优先队列 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;
}
//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;
}
相关文章推荐
- Dijkstra 最短路算法(只能计算出一条最短路径,所有路径用dfs)
- 轻松学算法7:Dijkstra最短路算法
- 【啊哈!算法】算法7:Dijkstra最短路算法
- 坐在马桶上看算法:Dijkstra最短路算法
- 最短路算法:Dijkstra和Flody详解
- Dijkstra最短路算法
- 【啊哈!算法】算法7:Dijkstra最短路算法
- 最短路算法之Dijkstra
- 最短路算法 堆优化 dijkstra+heap
- hdu 1595 最短路算法dijkstra
- 最短路算法详解(Dijkstra/SPFA/Floyd)
- 最短路算法之dijkstra
- dijkstra最短路算法--模板
- 优先队列Dijkstra实现最短路算法
- Dijkstra最短路算法
- hdu1874 畅通工程续 单源最短路算法——Dijkstra
- Dijkstra 最短路算法
- [转]【坐在马桶上看算法】算法7:Dijkstra最短路算法--作者:ahalei
- poj1062 昂贵的聘礼 (dijkstra最短路算法)
- 【坐在马桶上看算法】算法7:Dijkstra最短路算法