现在的位置: 首页 > 综合 > 正文

最短路算法Dijkstra

2014年06月12日 ⁄ 综合 ⁄ 共 2094字 ⁄ 字号 评论关闭

邻接矩阵,算法复杂度: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;
}

抱歉!评论已关闭.