dijkstra(数组实现n²,带打印路径)

dijkstra(数组实现n²,带打印路径)

算法思想(参考某算法模板,不知道挂哪的链接,纯属记录)

Dijkstra算法采用的是一种贪心的策略,声明一个数组lowcost来保存源点到各个顶点的最短距离和一个保存已经找到了最短路径的顶点的集合:T(用vis数组来标记),path存储路径前驱。

  • 初始化,vis[i] = 0, lowcost[i] = INF, cost[i] [j] = INF, cost[i] [i] = 0。
  • 初始时,lowcost[beg] = 0,vis[beg] = 1, path[beg] = -1。经过n-1轮,每轮选出一个距离源点最近的点u作为桥梁(可用堆来优化),如果lowcost[u] + cost[u] [j] < lowcost[j],就更新并且记录路径。选取u前设为-1,如果选取完之后u == -1,则无法到达目标点;期间如果找到了目标点可直接返回。
  • 打印路径需要逆序打印,这里用的递归。
/*==================================================*\
 | Dijkstra 数组实现 O(N^2)
 | Dijkstra --- 数组实现(在此基础上可直接改为STL的Queue实现) 
 | lowcost[] --- beg到其他点的最近距离
 | path[] -- beg为根展开的树,记录父亲结点
\*==================================================*/ 

#include<bits/stdc++.h>
using namespace std;

#define INF 0x03F3F3F3F 
#define N 105
 
int path[N], vis[N], cost[N][N], lowcost[N], n, m; 

void init(){
    for (int i = 0; i < n; ++i){
        for (int j = 0; j < n; ++j){
            if (i == j)
                cost[i][j] = 0;
            else
                cost[i][j] = INF;
        }
        lowcost[i] = INF;
        vis[i] = 0;
    }
}

void intput(){
    //cin >> n >> m;
    for (int i = 0; i < m; i++){
        int u, v, w;
        cin >> u >> v >> w;
        cost[u-1][v-1] = cost[v-1][u-1] = w;
    }
}

void output(int beg, int end){
    cout << lowcost[end] << endl;
}

void print(int k){		//打印路径
    if (-1 != k){
        print(path[k]);
        cout << k+1 << ' ';
    }
}

bool Dijkstra(int beg, int end){  
    vis[beg] = 1; 
    for (int i = 0; i < n; i++)
        lowcost[i] = cost[beg][i]; 
    lowcost[beg] = 0; 
    path[beg] = -1; // 树根的标记 
    for (int i = 1; i < n; i++){ 
        int u = -1;
        for (int j = 0; j < n; j++) 
            if (vis[j] == 0 && (u == -1 || lowcost[j] < lowcost[u]))
                u = j; 
        if (u == -1) return 0;
        if (u == end) return 1;
        vis[u] = 1;
        for (int j = 0; j < n; j++) 
            // 下面的加法可能导致溢出,INF不能取太大
            if (vis[j] == 0 && lowcost[u] + cost[u][j] < lowcost[j]){ 
                lowcost[j] = lowcost[u] + cost[u][j]; 
                path[j] = u; 
            } 
    }
    return 1; 
}

int main(){
    while (cin >> n >> m){
        if (n == 0 && m == 0)  return 0;
        init();
        intput();
        if (Dijkstra(0, n-1))  //	0:起点 n-1终点
            //for (int i = 0; i < n; i++)            
                output(0, n-1);
        //print(n-1);
    }
}

题目链接u.edu.cn/showproblem.php?pid=2544)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值