/**
dijkstra 是很经典的单源最短路算法,当年 迪杰斯特拉 就是靠这个算法拿了
图灵奖,此算法应用非常广泛,尤其在网络路由中。。
这里先介绍 dijkstra 的基本连接矩阵算法,在竞赛图算法中经常用到,复杂度为
O(N^2),后面再贴用优先队列优化的 O(N*logE) 算法
dijkstra 算法不仅仅用于求最短路,利用本身的算法结构和精妙的dis[] 数组,可以
解决图论中各种对点的计算。
对连接矩阵转置可变为单汇点最短路径。。
*/
const int inf = 0x3f3f3f3f;
const int M = 1000; //节点的个数,如果超过2000 个点,就应该考虑用邻接表的算法了
int map[M][M]; //连接矩阵初始化为 0
int dijkstra(int nv, int s, int t) { //源点为s 目标点为t
int count = nv-1, now = s;
int dis[M], vis[M], i;
for (i=1; i<=nv; i++) { //假设有nv 个结点,不包括零点,不过题目中一般会包括零点
d[i] = inf;
vis[i] = 0;
}
vis[s] = 1, dis[s] = 0; //dis[]如上篇bellman 一样,vis[i]为1 此时i 的最短路径已确定
while (count--) { //这是dijkstra 算法的核心,用到贪心向外层层扩展
int k=0, max = inf;
for (i=1; i<=nv; i++) {
if (!vis[i]) {
if (map[now][i] && dis[i] > map[now][i]+dis[now])
dis[i] = map[now][i] + dis[now];
if (max > dis[i]) {
k = i; //每次挑一个距离s 最短的结点 然后作为now 结点
max = dis[i];
}
}
}
now = k;
vis[k] = 1;
if (now == t)
break;
//理解这段代码最好的办法就是写几个点,用手画一下
}
return dis[t]; //返回s 到t 的最短路径
}
/**
注意:好多题目中会出现重边,重边的处理办法就是挑一条最短的边存入连接矩阵中
练习:POJ 1062 1797 2253 2387 2472 2502 3013 3037 3268
*/
收藏于 2011-11-17
来自于百度空间
dijkstra 算法
最新推荐文章于 2024-08-13 17:15:43 发布