[图论]最短路(Dijkstra算法)
Posted z354681250
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[图论]最短路(Dijkstra算法)相关的知识,希望对你有一定的参考价值。
/*
Name:最短路(Dijkstra)
Actor:HT
Time:2015年11月8日
Error Reporte: 1.map 字符串做下标时,别用char*,用string,记得加头文件
*/
#include"stdio.h"
#include"iostream"
#include"string.h"
#include"stdlib.h"
#include"string"
#include"map"
using namespace std;
//O(n^2)
//HDU2112 不完整代码
#define N 10010
#define INF 0x3f3f3f3f
map<string,int> imap; //地名处理
int stationsum; //总站数,用来协助处理地名
char start[40], iend[40];
char ta[40], tb[40];
int bigmap[155][155]; //邻接图
int visited[155];
int n;
int tl;
int d[155]; //原点到每个点的距离
int main()
int i, j;
while (scanf("%d", &n) != EOF)
memset(bigmap, 0x3f, sizeof(bigmap));
memset(d, 0x3f, sizeof(d));
scanf("%s %s", start, iend);
imap.clear(); //默认为0
stationsum = 3;
imap[start] = 1;
imap[iend] = 2;
for (i = 0; i < n; i++)
scanf("%s %s %d", ta, tb, &tl);
if (!imap[ta])
imap[ta] = stationsum;
stationsum++;
if (!imap[tb])
imap[tb] = stationsum;
stationsum++;
bigmap[imap[ta]][imap[tb]] = tl;
bigmap[imap[tb]][imap[ta]] = tl;
//printf("%s %s::%d %d %d\\n",ta,tb, imap[ta], imap[tb], bigmap[imap[ta]][imap[tb]]);
//Dij算法:每次找到d值最小的点,利用这个点更新一下其他所有点的d值
int m, k = 1;
d[1] = 0;
for (i = 0; i < n; i++)
m = INF;
for (j = 1; j < stationsum; j++) if (visited[j] == 0 && m > d[j])
k = j;
m = d[j];
visited[k] = 1;
for (j = 1; j < stationsum; j++)
if (d[j]>d[k] + bigmap[k][j])
d[j] = d[k] + bigmap[k][j];
printf("%d\\n", d[imap[iend]]);
return 0;
可以通过邻接表优化复杂度到O(mlogn),将所有边保存在邻接表中,然后每次遍历一个节点的自己的那一行表
倘若计算所有点互相的最短距离,就用Floyd算法,三重循环,先遍历所有节点i;对于每个节点i,遍历与其不同的节点j;对于i,j两点,遍历其他所有点k,利用i到k和k到j计算i到j的最短距离,相当暴力。
下面给出一个邻接表完成的简易示例,体会一下邻接表的使用:
//起点为节点4
#define INF 10000
//数组实现链表
int head[7] = 0 ; //表头
int next[50] = 0 ; //链
int dis[50]; //边长
int pos[50] = 0 ; //节点
int vis[7] = 0 ;
int d[7]; //所求每个点到4距离
int pre[7];
void initialize_table(); //邻接表初始化函数
int main()
initialize_table();
int i, j, k;
d[4] = 0;
int m;
//Dijkstra算法
for (i = 0; i < 6; i++)
m = INF;
for (j = 1; j <= 6; j++) //每次找d最小点
if (m > d[j] && vis[j] == 0)
m = d[j];
k = j;
vis[k] = 1;
j = head[k]; //开始检查邻接表
while (j)
if (d[pos[j]] > d[k] + dis[j])
d[pos[j]] = d[k] + dis[j];
pre[pos[j]] = k;
j = next[j];
for (i = 1; i < 7; i++) //输出格式
printf("4到%d点的最短距离:%d 路径:", i, d[i]);
j = i;
while (j != 4)
printf("%d<---", j);
j = pre[j];
printf("4\\n");
system("pause");
return 0;
void initialize_table() //将邻接表按题意图初始化
int i;
for (i = 0; i < 50; i++)
dis[i] = INF;
for (i = 0; i < 7; i++)
d[i] = INF;
pre[i] = -1;
head[1] = 0;
head[2] = 1;
pos[1] = 1;
dis[1] = 2;
next[1] = 2;
pos[2] = 4;
dis[2] = 5;
head[3] = 3;
pos[3] = 2;
dis[3] = 8;
next[3] = 4;
pos[4] = 6;
dis[4] = 4;
head[4] = 5;
pos[5] = 5;
dis[5] = 5;
next[5] = 6;
pos[6] = 6;
dis[6] = 2;
next[6] = 11;
pos[11] = 3;
dis[11] = 7;
head[5] = 7;
pos[7] = 1;
dis[7] = 9;
head[6] = 8;
pos[8] = 1;
dis[8] = 3;
next[8] = 9;
pos[9] = 2;
dis[9] = 6;
next[9] = 10;
pos[10] = 5;
dis[10] = 5;
以上是关于[图论]最短路(Dijkstra算法)的主要内容,如果未能解决你的问题,请参考以下文章