单源次短路径

本文介绍了一种解决单源最短路径问题的算法实现,包括所需的数据结构和操作步骤。通过具体的C++代码示例展示了如何寻找从一个源点到其他所有点的最短路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

// 单源最短路径问题的整理 
// 需要的数据结构:map[i][j]用来存放点与点之间的权used[i]用来标记点是否已经被用过dist[i]用来动态记录从 起点到该点的最短距离
// 具体的操作步骤
// 1. 初始化各项内容 
// 2. 在使用的点中找出已经求出的确定的最短路径,并标记为已使用 
// 3. 根据已经确定的最短路径的点,更新其余的dist[i] 
#include<iostream>
#include<vector> 
#define MAX_V 6000 //最多5000个顶点 
#define INF 5000   // 最长是5000 
using namespace std;
int V; 
int N;
int R; 
int map[MAX_V][MAX_V];
int dist[MAX_V];
int dist2[MAX_V];
bool used[MAX_V];
// solve的功能,找到以s为起点的到各个点的最短路径和次短路径 
void solve(int s){ // s是源点 
    fill(dist, dist + V, INF);
    fill(dist2, dist2 + V, INF);
    fill(used, used + V, false);
    dist[s] = 0;
    while(true){
        // 先找dist中的最小值,把这个值对应的点作为一个最近的点,同时标记为used
        int v = -1;
        int i;
        int a, b;
        for(i = 0; i < V; i++){
            if(!used[i] && (v == -1 || dist[i] < dist[v])) 
                v = i;
        } 
        if(v == -1)
            break;
        used[v] = true;
        for(i = 0; i < V; i++){
                dist[i] = min(dist[i], dist[v]+map[v][i]);
                int m = INF;
                for(int j = 0; j < V; j++){
                    a = dist[j]+map[i][j];
                    b = dist2[j] + map[i][j];
                    if(a == dist[i])
                        m = min(m, b);
                    else{
                        m = min(m,a);
                        m = min(m,b);
                    }   
                }
                dist2[i] = m;   
        }
    }
    cout <<dist2[V-1] << endl;
}
int main(){
    cin >> N >> R;
    V = N; 
    int x, y, d;
    for(int i = 0; i < V; i++){
        for(int j = 0; j < V; j++){
            map[i][j] = INF;
        }
    }
    for(int i = 0; i < R; i++){
        cin >> x >> y >> d;
        map[x-1][y-1] = d;
        map[y-1][x-1] = d;
    }
    solve(0);
//  system("pause");
    return 0;
} 
// 由于内存占用太大,poj上没有通过
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值