设为首页 收藏本站
查看: 1318|回复: 0

[经验分享] Dijkstra最短路径——2017华为实习在线机试

[复制链接]

尚未签到

发表于 2017-7-10 21:10:11 | 显示全部楼层 |阅读模式
  题目大致就是找到一个图的最短路径,没什么新意,不过关键是!关键是!我没写出来……
  上上篇文章——图的所有路径输出可以解决,不过要计算所有路径,工作量比较大,可能是超时。
  对于这种无负边的最短路径可以用Dijkstra求解。
  代码注释很全,可以直接看懂:


DSC0000.gif DSC0001.gif


#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <string>
#include <list>
#include <stack>
#include <queue>
using namespace std;

typedef struct point{
     int x;
     int y;
     point *previous;
     int step;
} point;

/*
int map[6][6] = {
     { 0, 2, 10, 5, 3, -1 },
     { -1, 0, 12, -1, -1, 10 },
     { -1, -1, 0, -1, 7, -1 },
     { 2, -1, -1, 0, 2, -1 },
     { 4, -1, -1, 1, 0, -1 },
     { 3, -1, 1, -1, 2, 0 }
};*/
int map[6][6] = {
     { -1, 2, 10, -1, 3, -1 },
     { -1, -1, 12, -1, -1, 10 },
     { -1, -1, -1, -1, 7, -1 },
     { -1, -1, -1, -1, -1, -1 },
     { 4, -1, -1, -1, -1, -1 },
     { 3, -1, 1, -1, 2, -1 }
};
/*
int map[6][6] = {
     {-1,-1,10,-1,30,100},
     {-1,-1,5,-1,-1,-1},
     {-1,-1,-1,50,-1,-1},
     {-1,-1,-1,-1,-1,10},
     {-1,-1,-1,20,-1,60},
     {-1,-1,-1,-1,-1,-1},
};*/
/*
int map[6][6] = {
     { -1, -1, 10, -1, 30, 100 },
     { -1, -1, 5, -1, -1, -1 },
     { -1, -1, -1, 50, -1, -1 },
     { -1, -1, -1, -1, -1, 10 },
     { -1, -1, -1, 20, -1, 60 },
     { -1, -1, -1, -1, -1, -1 },
};*/
void PrintMostShortPath(vector<int> path, vector<int> D, int startPoint, int endPoint)
{
     int s = endPoint;
     vector<int> v;
     v.push_back(endPoint);

     while (path != startPoint)
     {
         v.push_back(path);
         s = path;
     }
     v.push_back(startPoint);

     cout << "最短路径为:";
     for (int i = v.size() - 1; i >= 0; i--)
     {
         cout << " " << v;
     }
     cout << endl;
     cout << "最距离为为:" << D[endPoint] << endl;
}

void PrintIntVector(vector<int> v)
{
     for (int i = 0; i < v.size(); i++)
     {
         cout << v << "\t";
     }
     cout << endl;
}
void PrintBoolVector(vector<bool> v)
{
     for (int i = 0; i < v.size(); i++)
     {
         cout << v << "\t";
     }
     cout << endl;
}

//算法对于负边图无效
void Dijkstra(int startPoint,int endPoint)
{
     //获取图边长
     int n = 6;

     //初始化变量
     vector<bool> S(n);//标记节点是否走过
     vector<int> D(n);//从起点到该点的最短距离
     vector<int> Path(n);//该点的前驱节点
     int v = 0;
     int min = 0;

     //初始化变量
     for (int i = 0; i < n; i++)
     {
         S = false;
         D = map[startPoint];
         //有边
         if (D >0)
         {
             Path = startPoint;
         }
         else
         {
             Path = -1;
         }
     }
     S[startPoint] = true;
     D[startPoint] = 0;

     //初始化打印
     cout << "已经走过的节点S:    "; PrintBoolVector(S);
     cout << "当前最短路径D:        "; PrintIntVector(D);
     cout << "前驱符号Path:        "; PrintIntVector(Path);

     //再循环n-1次,把剩下的n-1个节点都走一遍
     for (int j = 1; j < n; j++)
     {
         min = 32767;
         v = 0;

         //寻找当前最短路径D中,未走过并且,可以到达的,距离最短节点。
         for (int i = 0; i < n; i++)
         {
             if (S == false && D != -1 && (D < min))
             {
                 v = i;
                 min = D;
             }
         }
         S[v] = true;//v为中转节点,标记走过

         //以v为中转点走到i节点和现有到i路径比较
         for (int i = 0; i < n; i++)
         {
             //这个||很关键。两种需要更新的情况。一种是通过中转小于目前的最短距离,另一种是直接可以到的(在map中有v到i的路径)
             //第一个:没走过的点,第二个:能走的点,第三个:1.通过中转点走比直接走小2.在map中v-i可以走,但是在D中未更新的情况
             //dijkstra关键有就是一个更新的操作
             if (S == false && map[v] != -1 && (D[v] + map[v] < D || D == -1))
             {
                 D = D[v] + map[v];
                 Path = v;
             }
         }

         //打印每次的结果
         cout << "第" << j << "次:" << endl;
         cout << "已经走过的节点S:    "; PrintBoolVector(S);
         cout << "当前最短路径D:        "; PrintIntVector(D);
         cout << "前驱符号Path:        "; PrintIntVector(Path);
     }
     PrintMostShortPath(Path, D, startPoint, endPoint);
}

int main()
{
     int startPoint = 4;
     int endPoint = 1;

     Dijkstra(startPoint, endPoint);

     return 0;
}
View Code  结果如下
DSC0002.png

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-392550-1-1.html 上篇帖子: 华为实习日记——第二十八天 下篇帖子: 华为OJ:数字颠倒
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表