美文网首页
最短路径

最短路径

作者: 1nvad3r | 来源:发表于2020-09-05 10:18 被阅读0次
Dijkstra算法:

邻接矩阵:

#include <algorithm>

using namespace std;
const int maxn = 1010;
const int INF = 1 << 30;

int G[maxn][maxn];
int d[maxn];//起点到达各顶点的最短路径长度
int pre[maxn];//pre[v]表示从起点到顶点v的最短路径上v的前一个顶点
bool isVisit[maxn];
int n;

void dijkstra(int st) {
    fill(d, d + maxn, INF);
    d[st] = 0;
    for (int i = 0; i < n; i++) {
        int u = -1, min = INF;
        for (int j = 0; j < n; j++) {
            if (isVisit[j] == false && d[j] < min) {
                u = j;
                min = d[j];
            }
        }
        if (u == -1) {
            return;
        }
        isVisit[u] = true;
        for (int j = 0; j < n; j++) {
            if (isVisit[j] == false && G[u][j] != INF && d[u] + G[u][j] < d[j]) {
                d[j] = d[u] + G[u][j];
                pre[j] = u;
            }
        }
    }
}

//起点s到顶点v的最短路径
void dfs(int s, int v) {
    if (v == s) {
        printf("%d\n", s);
        return;
    }
    dfs(s, pre[v]);
    printf("%d\n", v);
}

邻接表:

#include <vector>
#include <algorithm>

using namespace std;

const int maxn = 1010;
const int INF = 1 << 30;
struct Node {
    int v, dis;
};

vector<Node> G[maxn];
int n;
int d[maxn];
int pre[maxn];//pre[v]表示从起点到顶点v的最短路径上v的前一个顶点
bool isVisit[maxn];

void dijkstra(int st) {
    fill(d, d + maxn, INF);
    d[st] = 0;
    for (int i = 0; i < n; i++) {
        int u = -1, min = INF;
        for (int j = 0; j < n; j++) {
            if (isVisit[j] == false && d[j] < min) {
                u = j;
                min = d[j];
            }
        }
        if (u == -1) {
            return;
        }
        isVisit[u] = true;
        for (int j = 0; j < G[u].size(); j++) {
            int v = G[u][j].v;
            if (isVisit[v] == false && d[u] + G[u][j].dis < d[v]) {
                d[v] = d[u] + G[u][j].dis;
                pre[v] = u;
            }
        }
    }
}

void dfs(int s, int v) {
    if (v == s) {
        printf("%d\n", s);
        return;
    }
    dfs(s, pre[v]);
    printf("%d\n", v);
}
dijkstra+DFS解决单源点最短路径通用方案:

1.先用万能模板记录所有最短路径(无需修改任何代码)。

#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

const int MAXV = 510;//最大顶点数
const int INF = 1000000000;//无穷大
//n为顶点数,m为边数,start为起点,end为终点,G为邻接矩阵
int n, m, start, end, G[MAXV][MAXV];
//d记录到起点的最短距离
int d[MAXV];
bool isVisit[MAXV] = {false};//true表示顶点i已访问

vector<int> pre[MAXV];//存放结点v的所有能产生最短路径的前驱结点

void dijkstra(int s) {//s为起点
    fill(d, d + MAXV, INF);
    d[s] = 0;
    for (int i = 0; i < n; i++) {
        int u = -1, MIN = INF;
        for (int j = 0; j < n; j++) {
            if (isVisit[j] == false && d[j] < MIN) {
                u = j;
                MIN = d[j];
            }
        }
        if (u == -1) {
            return;
        }
        isVisit[u] = true;
        for (int j = 0; j < n; j++) {
            if (isVisit[j] == false && d[u] + G[u][j] < d[j]) {
                d[j] = d[u] + G[u][j];
                pre[j].clear();
                pre[j].push_back(u);
            } else if (isVisit[j] == false && d[u] + G[u][j] == d[j]) {
                pre[j].push_back(u);
            }
        }
    }
}

2.遍历所有最短路径,找出一条使第二标尺最优的路径。

void dfs(int v) {//v为当前结点
    tempPath.push_back(v);//将当前结点加入临时路径最后面
    if (v == st) {
        num++;
        int value = 0;//存放临时路径tempPath上第二标尺的值
        计算路径tempPath上的value值;
        if (value优于optValue) {
            optValue = value;
            path = tempPath;
        }
        tempPath.pop_back();
        return;
    }
    //递归式
    for (int i = 0; i < pre[v].size(); i++) {
        dfs(pre[v][i]);//结点v的前驱结点pre[v][i],递归
    }
    tempPath.pop_back();//遍历完所有前驱结点,将当前结点v删除
}

1003 Emergency

1018 Public Bike Management

1030 Travel Plan

1072 Gas Station

1087 All Roads Lead to Rome

Floyd算法:
const int maxn = 210;
const int INF = 1 << 30;
int n, m;//顶点数,边数
int dis[maxn][maxn];//dis[i][j]表示i和j的最短距离

void floyd() {
    for (int k = 0; k < n; k++) {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (dis[i][k] != INF && dis[k][j] != INF && dis[i][k] + dis[k][j] < dis[i][j]) {
                    dis[i][j] = dis[i][k] + dis[k][j];
                }
            }
        }
    }
}

相关文章

  • 图的应用-最短路径求解

    图的最短路径   图的最短路径是一个起点到一个终点之间最短的路径。  用于解决最短路径问题的算法被称做“最短路径算...

  • Yen的K条最短路径算法(KSP)

    一、问题介绍 1.求K条最短路径的必要性 最短路径问题分为: 单源最短路径 所有顶点对间的最短路径 共同的缺陷:这...

  • 最短路径算法

    最短路径算法可以分为两类:单源最短路径问题:从某固定源点出发,求其到所有其他顶点的最短路径。多源最短路径问题:求任...

  • 最短路径 之 Dijkstra 算法

    • 最短路径 之 Floyd 算法• 最短路径 之 Bellman 算法 Dijkstra算法是用于求解单源最短路...

  • 数据结构第二季 Day11 图 Kruskal算法、Dijkst

    一、最短路径基础知识 1、最短路径的定义是什么? 最短路径(Shortest Path):两顶点之间权值之和最小的...

  • 图 求解最短路径 时间复杂度 空间复杂度 单源最短路径 多源最短路径 条数最短(点权为1) 边权之和最小或最大(花...

  • 最短路径问题

    无权图单源最短路径 有权图单源最短路径 有权图单源最短路径和无权图最短路径不一样,不能单从节点数来看,比如上图中,...

  • 最短路径

    最短路径 最短路径:http://baike.baidu.com/view/349189.htmDijkstra算...

  • 算法之「迪杰斯特拉(Dijkstra)算法」

    最短路径 生活中,我们常常会面临着对路径的最优选择问题,可能是路程最短,也可能是时间最短,这个的最短路径就类似路程...

  • 数据结构与算法-图的最短路径Dijkstra算法&Floyd算法

    最短路径 最短路径问题是图论研究中的一个经典算法问题, 旨在寻找图(由结点和路径组成的)中两结点之间的最短路径。在...

网友评论

      本文标题:最短路径

      本文链接:https://www.haomeiwen.com/subject/xxttektx.html