dijkstra 算法

/**
    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
来自于百度空间

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值