训练题目——图的广度优先遍历
哈喽,大家好,我是赏月君,今天做一下图论的题目——图的广度优先遍历,废话少说,上题目。
题目描述
请编写一个程序,求给定的有向图G =(V, E)中顶点1到各顶点的最短路径d (路径边数的最小值)。各顶点编号分别为1至n。如果从顶点1出发无法到达某顶点,则与该顶点的距离记为-1。
输入
第1行输人G的顶点数n。接下来n行按如下格式输人各顶点u的邻接表。
u k v1 v2 … vk
其中u为顶点编号,k为u的度,v1 v2 … vk 为与u相邻的顶点编号。
输出
按顶点编号顺序输出各顶点的id、d,每个顶点占1行。id为顶点编号,d为顶点1到该顶点的距离。
限制
1≤n≤ 100
输入样例
4
1 2 2 4
2 1 4
3 0
4 1 3
输出样例
1 0
2 1
3 2
4 1
题目思路
利用类、对列、标记数组解决问题。
C++代码实现
#include<bits/stdc++.h>
#define ll long long //自定义类型名称
#define inf 0x3f3f3f3f //定义无穷大变量
#define maxn 109
using namespace std;
int f[maxn];
vector<int> son[maxn];//类
bool vis[maxn];//标记数组
int d[maxn];
void bfs(){//广搜算法
queue<int> q;//定义队列
vis[1]=1;//标记已经搜索
q.push(1);//入队
d[1]=0;//一开始的距离为0
while(!q.empty()){//只要队列不空
int now=q.front();
q.pop();
for(int i=0;i<son[now].size();i++){
int x=son[now][i];
if(!vis[x]){//没有搜过
vis[x]=1;
d[x]=d[now]+1;//距离加一
q.push(x);
}
}
}
}
int main(){
memset(d,-1,sizeof(d));//初始化数组全部为-1
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
int id;
scanf("%d",&id);
int k;
scanf("%d",&k);
for(int j=1;j<=k;j++){
int vi;
scanf("%d",&vi);
son[id].push_back(vi);//将其放入最后面
}
}
bfs();//广搜
for(int i=1;i<=n;i++){
printf("%d %d\n",i,d[i]);
}
}
OK,解决了。