寻找无向图的最短路径(有跳数限制)

需要寻找一条有效的最短路径。给定一个无向网络G=(V,A,C),其中V是节点集合,A是无向边集合,C是边路径长度集合,对于每条边a(i,j),对应有c(i,j)>=0。当给定两节点(源点和汇点)以及跳数pathLength,求解两点之间的最短距离,要求其跳数满足大于pathLength。
要求:设计算法,分析其时间复杂度。请提供源程序。输入的测试数据如下所示:

7 12 2

0 1 2 3 4 5 6

0 4 74

1 4 60

2 4 60

3 4 97

5 0 100

5 1 100

5 2 100

5 3 100

6 0 100

6 1 100

6 2 100

6 3 100

数据说明如下:

第1行:7表示7个节点;12表示12条链路;2表示跳数pathLength。

第2行:0 1 2 3 4 56:表示有7个节点,节点标识为0,1,…,6。

第3-14行:表示边,如0 4 74表示节点0到节点4的边距离为74。

#include <iostream>
#include <unordered_map>
#define INF 2147483647
using namespace std;
unordered_map<int,int>nameToIndex;
unordered_map<int,int>indexToName;

int vexNum;
int edgeNum;
int pathLendth;
int vS;
int vD;//源点,目标点
int res[120];//保存被访问的路径节点 
int minL = INF;//最短路径 
int num;
int path[120];//前驱
int g[120][120];//领接矩阵存储边
int isVisited[120];//节点访问情况

void Dfs(int index,int sum) { //index为已访问的点个数,sum为总长
    if(sum>=minL) {
        return;//没找到更小的路径,直接退出
    } else if(path[index-1]==vD) { //找到了目标点
        if(index-1>pathLendth && sum<minL) { //满足跳数和最小
            for(int i = 0; i<index; i++) {
                res[i] = path[i];//将path数组复制 
            }
            minL = sum;
            num = index;
        }
        return;//结束
    } else {
        for(int i = 0; i<vexNum; i++) { //遍历点
            if(!isVisited[i] && g[path[index-1]][i]<INF) { //没被访问且有边
                path[index] = i;//将点i存储在path数组 
                isVisited[i] = 1;//i被访问
                Dfs(index+1,sum+g[path[index-1]][i]);//递归访问下一个
                isVisited[i] = 0;//回溯
            }
        }
    }
}

int main() {
    printf("请输入点数,边数,跳转数\n");
    scanf("%d %d %d",&vexNum,&edgeNum,&pathLendth);
    for(int i = 0; i<vexNum; i++) { //初试化边
        for(int j = 0; j<vexNum; j++) {
            g[i][j] = INF;
        }
    }
    printf("输入节点标识\n");
    int tmpName;
    int tmpIndex = 0;
    for(int i = 0; i<vexNum; i++) {
        scanf("%d",&tmpName);//读取点的值
        nameToIndex[tmpName] = tmpIndex;//记录值与数组下标的对应关系
        indexToName[tmpIndex] = tmpName;
        tmpIndex++;
    }

    int tmpV1;
    int tmpV2;
    int tmpL;
    printf("请输入点A,点B,边长\n");
    for(int i = 0; i<edgeNum; i++) {
        scanf("%d %d %d",&tmpV1,&tmpV2,&tmpL);
        tmpV1 = nameToIndex[tmpV1];
        tmpV2 = nameToIndex[tmpV2];
        g[tmpV1][tmpV2] = tmpL;//邻接矩阵存储边
        g[tmpV2][tmpV1] = tmpL;
    }
    for(int i = 0; i<vexNum; i++) {
        isVisited[i] = 0;//访问情况初始化
    }

    printf("源点,目标点\n");
    scanf("%d  %d",&vS,&vD);
    vS = nameToIndex[vS];//获取源点下标
    vD = nameToIndex[vD];//目标点下标

    isVisited[vS] = 1;
    path[0] = vS;//初始化
    Dfs(1,0);

    if(minL<INF) {
        printf("%d\n",minL);
        printf("路径为:");
        for(int i = 0; i<num; i++) {
            printf("%d   ",res[i]);
        }
    } else {
        printf("不存在\n");
    }
    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 图的最短路径 迪杰斯特拉算法 贝尔曼-福特算法 弗洛伊德算法 SPFA算法(中国西南交通大学段凡丁发明) 最短路径...
    董泽平阅读 493评论 0 1
  • 前言 本专题旨在快速了解常见的数据结构和算法。 在需要使用到相应算法时,能够帮助你回忆出常用的实现方案并且知晓其优...
    蛮三刀酱阅读 3,447评论 0 0
  • 摘要 最短路径问题是一个在图论研究中很经典的问题,已经被应用到GIS、GPS等信息管理系统中,为人们生活带来了很大...
    你本无意穿堂风_a69c阅读 645评论 2 3
  • 摘要 最短路径问题是一个在图论研究中很经典的问题,已经被应用到GIS、GPS等信息管理系统中,为人们生活带来了很大...
    偏偏孤倨引山洪阅读 319评论 0 1
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,625评论 28 53