二十三、图的广度优先遍历
题目描述
程序的输入是无向图的顶点序列和边序列(顶点序列以*为结束标志,边序列以-1,-1为结束标志)。程序的输出为图的邻接表和广度优先遍历序列。例如:
程序输入为:
a
b
c
d
e
f
*
0,1
0,4
1,4
1,5
2,3
2,5
3,5
-1,-1
程序的输出为:
the ALGraph is
a 4 1
b 5 4 0
c 5 3
d 5 2
e 1 0
f 3 2 1
the Breadth-First-Seacrh list:aebfdc
测试输入 | 期待的输出 | 时间限制 | 内存限制 | 额外进程 | |
---|---|---|---|---|---|
测试用例 1 | a b c d e f * 0,1 0,4 1,4 1,5 2,3 2,5 3,5 -1,-1 | the ALGraph is a 4 1 b 5 4 0 c 5 3 d 5 2 e 1 0 f 3 2 1 the Breadth-First-Seacrh list:aebfdc | 1秒 | 64M | 0 |
解题思路
用一个 node
结构来模拟邻接表,data表示边表的头结点(头结点可能不止一个字符,最好用字符数组),num表示该边表中依附了几个结点,list[] 数组存储依附的结点编号,map[] 数组模拟顶点表,这样一个邻接表就模拟出来了。
同时,因为我们在之后还要进行广度优先遍历,所以还需要添加一个标记位 vis,来检测当前结点是否被标记过。
struct node
{
char data[10]; //边表头结点
int list[100]; //边表中各个结点编号
int num; //边表中连接的结点数
int vis; //标记位
}map[100]; //顶点表
一点值得注意的是,本题输入的是无向图,所以对于一条输入的边序列(x,y),我们需要建立两条边。
map[x].list[map[x].num] = y;
map[x].num++;
map[y].list[map[y].num] = x;
map[y].num++;
当我们用 bfs 遍历求解时,为了避免多次重复遍历,用一个 for 循环,判断结点的 vis 不为 0,则跳过该结点的遍历。
上机代码
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<algorithm>
using namespace std;
struct node
{
char data[10];//边表头结点
int list[100];//边表中各个结点编号
int num; //边表中连接的结点数
int vis; //标记位
}map[100]; //顶点表
int counts = 0, x, y;
void bfs(int n)
{
queue<int>q;
int ans = n;
int tmp;
map[ans].vis = 1;
q.push(ans);
while (!q.empty())
{
ans = q.front();
q.pop();
printf("%c", map[ans].data[0]);
if (map[ans].num == 0)
continue;
for (int k = map[ans].num - 1; k >= 0; k--)
{
tmp = map[ans].list[k];
if (map[tmp].vis == 1)
continue;
q.push(tmp);
map[tmp].vis = 1;
}
}
}
int main()
{
while (~scanf("%s",&map[counts].data))//输入节点
{
if (map[counts].data[0] == '*')
break;
counts++;
}
while (~scanf("%d,%d", &x, &y))//输入邻接表
{
if (x == -1 && y == -1)//结束标志
break;
//无向图需要建立两条边
map[x].list[map[x].num] = y;
map[x].num++;
map[y].list[map[y].num] = x;
map[y].num++;
}
printf("the ALGraph is\n");
for (int i = 0; i < counts; i++)//打印邻接表
{
printf("%c", map[i].data[0]);
for (int j = map[i].num - 1; j >= 0; j--)
{
printf(" %d", map[i].list[j]);
}
printf("\n");
}
printf("the Breadth-First-Seacrh list:");
for (int i = 0; i < counts; i++)//bfs序列
{
if (map[i].vis == 0)
bfs(i);
}
printf("\n");
//system("pause");
return 0;
}