持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第28天,点击查看活动详情
一、题目
描述:
学校开学,就会迎来很多新生,新生对学校不熟悉,现在需要一个小程序来帮助这些新生熟悉我们学校的各个重要建筑。
给出n个建筑,并且给出每个建筑可以走的路径和路径的具体距离值,要求随机给出两个建筑,请输出两个建筑的最短路径。
#include <iostream>
#include <vector>
#include <limits>
using namespace std;
struct Node{
inline Node(string name): name(name){}
inline void append(size_t node, int num) { route.push_back(node); distance.push_back(num); }
string name;
vector<size_t> route;
vector<int> distance;
};
vector<Node*> shortestDistanceRoute(vector<Node*>& nodes, size_t start, size_t end)
{
}
int main(int, char*[])
{
vector<Node*> nodes;
Node* node1 = new Node("二号门");
Node* node2 = new Node("三号门");
Node* node3 = new Node("共青团花园");
Node* node4 = new Node("光大礼堂");
Node* node5 = new Node("半月楼");
Node* node6 = new Node("行署楼");
Node* node7 = new Node("中心图书馆");
Node* node8 = new Node("田家炳");
Node* node9 = new Node("竹园");
Node* node10 = new Node("橘园");
nodes.push_back(node1);
nodes.push_back(node2);
nodes.push_back(node3);
nodes.push_back(node4);
nodes.push_back(node5);
nodes.push_back(node6);
nodes.push_back(node7);
nodes.push_back(node8);
nodes.push_back(node9);
nodes.push_back(node10);
node1->append(2, 350);
node3->append(0, 350);
node3->append(8, 600);
node3->append(3, 800);
node9->append(2, 600);
node9->append(3, 800);
node4->append(2, 800);
node4->append(8, 800);
node4->append(1, 400);
node4->append(6, 150);
node2->append(3, 400);
node7->append(3, 150);
node7->append(4, 200);
node7->append(5, 550);
node5->append(6, 200);
node5->append(9, 450);
node5->append(7, 500);
node6->append(6, 550);
node6->append(7, 200);
node8->append(5, 200);
node8->append(4, 500);
node8->append(9, 400);
node10->append(7, 400);
node10->append(4, 450);
for(Node* node : shortestDistanceRoute(nodes, 0, 3)){
cout << node->name << "->";
}
cout << endl;
return 0;
}
二、分析
由题意可知,要获取最短路径,最简单的方法就是穷举,然后取其中最近的一条。 由于整个路径构成了一张图,存在多个环,避免在穷举之时陷入死循环,我们需要一个状态量来做标志。 这时,我们便可以进行走动,从出发点开始,遍历可以走的每条路径,在走了一步之后,将这一步记录下来,在他的下一步遍历时,避免再走回来。 碰到终点后结束,记录下行走的路径和距离,和上一个路径做对比,第一次走就直接视为最短。 再行走途中,也可以动态比较已经走的距离和最短距离,如果已经超过最短距离,就代表此路过长,不用走了。 往回退时,需要把走的距离和地点删除,返回到原有的状态才能正确模拟。
三、模拟
- 二号门->共青团花园 350
- 共青团花园->竹园 950
- 竹园->光大礼堂 1750
- 共青团花园->光大礼堂 1150
四、实现
void dfs(vector<Node*>& nodes, vector<Node*>& result, bool* map, size_t start, size_t end, int& min, int cmin, vector<Node*>& current)
{
if(start == end){
if(cmin < min){
min = cmin;
result = current;
}
}else{
if(map[start]) return;
map[start] = true;
for(size_t i = 0; i < nodes.at(start)->route.size(); ++i){
size_t node = nodes.at(start)->route.at(i);
cmin += nodes.at(start)->distance.at(i);
current.push_back(nodes.at(start));
dfs(nodes, result, map, node, end, min, cmin, current);
current.pop_back();
cmin -= nodes.at(start)->distance.at(i);
}
map[start] = false;
}
}
vector<Node*> shortestDistanceRoute(vector<Node*>& nodes, size_t start, size_t end)
{
vector<Node*> result;
bool map[10] = {false};
int min = std::numeric_limits<int>::max();
vector<Node*> current;
dfs(nodes, result, map, start, end, min, 0, current);
result.push_back(nodes.at(end));
return result;
}
五、结言
最短路径的解决办法有很多种,最简单的就是遍历,掌握好遍历的原理,才能更好的去优化。
创作不易,留个赞再走吧!如果对文章内容有任何指正,欢迎评论!