这一部分在《啊哈!算法》里的 第五章. 图的遍历. 第3节 最少转机——图的广度优先遍历 中,但是是纯C的,我把它用C++队列实现了一下
题目:
小哼和小哈一同坐飞机去旅游,现在他们位于1号城市,目标是5号城市,可是1号城市并没有到5号城市的直航。不过小哼已经搜集了很多航班的信息,现在小哼希望找到一种乘坐方式,使得转机次数最少,如何解决呢?
分析:
BFS算法可以帮助我们完成这一目的。当然dfs也可以,但是实现在边的权值都相同的情况下,BFS更快~
代码:
//#include<iostream>
//#include<queue>
#include<bits/stdc++.h>//万能头文件
using namespace std;
struct node{
int x, s; //x:城市编号 s:转机次数
};
int main(){
int n, m, first, last; //n:城市个数 m:航线条数 first:出发城市 last:终点城市
cin>>n>>m>>first>>last;
int e[n+1][n+1], book[n+1]={0};
memset(e,-1,sizeof(e));//邻接矩阵所有元素初始化为-1
for(int i=1;i<=m;i++){
int a,b;
cin>>a>>b;
e[a][b]=1;
e[b][a]=1;
}
queue<node> q;
//把起点城市入队
node start;
start.x=first, start.s=0;
q.push(start);
book[start.x]=1;
//或者 q.push({ first,0 }); 这样更简单
//BFS
int flag=0;
while(!q.empty()){
node a=q.front();
for(int i=1;i<=n;i++){
node b;
if(e[a.x][i]!=-1&&book[i]==0){
//注意 e[x][y] = -1 的意思是:点x、y之间不是邻接点的意思
b.x=i, b.s=a.s+1;
q.push(b);
//上边两个可以直接 q.push({i,a.s+1}); 这样更简单
book[i]=1;
}
if(b.x==last){//已经扩展到了终点城市,停止扩展,任务结束退出循环
flag=1;
break;
}
}
if(flag==1) break;
q.pop();//当一个节点扩展完后,将其出队
}
cout<<"最短路径的长度为:"<<q.back().s;//注意这里是q.back()
return 0;
}
测试用例:
/* 测试用例
5 7 1 5
1 2
1 3
2 3
2 4
3 4
3 5
4 5
*/
结果:
最短路径的长度为:2
但是如何将路线打印出来呢?