BFS 和 DFS ( 2 ) —— 不带权的最短路径

参考:https://www.bilibili.com/video/av25763384/?spm_id_from=333.788.videocard.0

 

 

一,BFS 与最短路径

1,BFS 生成树

  通过 BFS 搜索顺序得到的生成树叫 BFS 生成树。

  因为 BFS 是一层一层的向外扩展的,所以该树上根节点到其余所有结点的路径起始就代表着起点到其余所有点的不带权的最短路径。

2,代码实现

  用数组 p 记录 BFS 生成树,要找根结点到 点v 的最短路径直接从 点v 向上遍历到根节点即可。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<vector>
#include<queue>
#include<stack>
#include<map>
using namespace std;
map<char, vector<char>>v;  // 邻接表
map<char, char>p;
void BFS(char start)
{
	// 创建队列,并添加起点
	queue<char>q;
	vector<int>vis;
	q.push(start);
	vis.push_back(start);
	p[start] = 0;

	while (q.size())
	{
		// 队首出队列
		char vertex = q.front();
		q.pop();

		// 取 vertex 的所有邻接点
		vector<char>vs = v[vertex];
		for (int i = 0; i < vs.size(); i++)
		{
			char next = vs[i]; // 邻接点
			auto ret = find(vis.begin(), vis.end(), next);
			if (ret == vis.end())  // 如果 next 没有遍历过的话
			{
				q.push(next);
				vis.push_back(next);
				p[next] = vertex;
			}
		}
	}
}
void find(char i)
{
	if (p[i] != 0)
	{
		find(p[i]);
		printf("->%c", i);
	}
	else
		printf("%c", i);
}
int main(void)
{
	int n, m;
	while (scanf("%d%d", &n, &m) != EOF)
	{
		char s, s1, s2;
		scanf("%c%c%c", &s1, &s, &s2);  // 起点
		for (int i = 0; i < m; i++)
		{
			char t1, t2, t3, t4;
			scanf("%c%c%c%c", &t1, &t3, &t2, &t4);
			vector<char>vv = v[t1]; // 取出 t1 原来的所有邻接点
			vv.push_back(t2);		// 增加一个邻接点
			v[t1] = vv;				// 覆盖掉原来的邻接点
		}
		BFS(s);

		// 输出最短路径
		for (auto i = v.begin(); i != v.end(); i++)
		{
			if ((*i).first == s)
				continue;
			printf("%c 到 %c 的最短路径:", s, (*i).first);
			find((*i).first);
			puts("");
		}
	}
	system("pause");
	return 0;
}
/*
测试数据:
6 16
A
A B
A C
B A
B C
B D
C A
C B
C D
C E
D B
D C
D E
D F
E C
E D
F D
测试结果:
A 到 B 的最短路径:A->B
A 到 C 的最短路径:A->C
A 到 D 的最短路径:A->B->D
A 到 E 的最短路径:A->C->E
A 到 F 的最短路径:A->B->D->F
*/

 

========== ======== ======== ======= ====== ===== ==== === == =

 

posted @ 2020-03-07 01:09  叫我妖道  阅读(198)  评论(0编辑  收藏  举报
~~加载中~~