啊哈!算法 ——5.2与5.3城市地图与最少转机数的对比

题意:
小哼和小哈一起坐飞机旅游,他们现在位于1号城市,目标是5号城市,可是1号城市没有到5号城市直航,不过他们收集了很多航班信息,现在他们要找出转机次数最少的方案,输出转机次数。

第一行的5表示有5个城市(编号为1~5),7表示有7条航线,1表示起始城市,5表示目标城市,接下来的每行“a b”,表示a,b之间有航线,也就是a,b之间可以相互到达。

样例:

5 7 1 5
1 2
1 3
2 3
2 4
3 4
3 5

输出

2

1.深度优先

#include<iostream>
using namespace std;

int book[101], min=99999999, m,n, e[101][101],startt, endd;

void dfs(int cur, int dis)
{
	if (dis > min)
		return;
	if (cur == endd)
	{
		if (min > dis)
			min = dis;
		return;
	}

	for (int i = 1; i <= m; i++)
	{
		if (e[cur][i] != 999999 && book[i] == 0)
		{
			book[i] = 1;
			dfs(i,dis+1);
			book[i] = 0;
		}
	}
	return;
}

int main()
{
	int a, b, l;
	cin >> m >> n >> startt >> endd;

	for (int i = 1; i <= m; i++)
		for (int j = 1; j <= m; j++)
			e[i][j] = 999999;

	for (int i = 1; i <= n; i++)
	{
		cin >> a >> b;
		e[a][b] = 1;
		e[b][a] = 1;
	}

	book[1] = 1;
	dfs(1, 0);
	cout << min << endl;

	return 0;
}

2.广度优先

#include<iostream>
using namespace std;

int book[101], min=99999999, m,n, e[101][101],startt, endd;

struct note
{
	int x;
	int dis;
}que[100000];

int main()
{
	int head, tail, sum=0;
	int a, b;
	cin >> m >> n >> startt >> endd;

	for (int i = 1; i <= m; i++)
		for (int j = 1; j <= m; j++)
			e[i][j] = 999999;

	for (int i = 1; i <= n; i++)
	{
		cin >> a >> b;
		e[a][b] = 1;
		e[b][a] = 1;
	}

	//队列初始化
	head = 1;
	tail = 1;
	que[1].x = startt;
	que[1].dis = 0;
	tail++;

	//从startt号城市出发
	book[startt] = 1;

	while (head < tail)
	{
		int cur = que[head].x;
		for (int i=1; i<=n; i++)
		{
			if (book[i] == 0 && e[cur][i] ==1)
			{
				que[tail].x = i;
				que[tail].dis = que[head].dis + 1;
				tail++;
				book[i] = 1;
			}
			if (que[tail-1].x == endd)
			{
				cout << que[tail-1].dis << endl;
				//遇到目标点时直接退出即可,联想队列,此时遍历到目标点,
				//每次用que[tail].dis = que[head].dis,即非常巧妙的记录路径深度变化
				return 0;
			}
		}
		head++;
	}

	cout << "impossible!" << endl;
	return 0;
}

在5.2的城市地图中,作者采用深度优先,该情况是给出边的权值不同的情况;
在5.3的最少转机数中,作者采用广度优先,该情况中,我们假设所有边的长度都是1,每一个线段表示一个转机,求最少转机就是求最短路径而已
因此可以得到:深度优先和广度优先的方法都可以,但是广度优先更适合所有边的权重一样的情况

在深度优先遍历中使用了递归的方法,该算法的时间复杂度为O(n²),n为点的个数
广度优先遍历中使用了标记数组的方法,该算法的时间复杂度为O(n+e),其中e为图中边的个数.
对于空间复杂度来说,两者的储存类型都是一样的,所以空间复杂度是相同的.综合对比两个遍历算法,各有优点,而且遍历所得的结果不同,在实际使用的时候要考虑问题的实现方法来综合考量两种算法.

参考:https://blog.csdn.net/Dragon_i/article/details/84981602

发布了7 篇原创文章 · 获赞 3 · 访问量 419

猜你喜欢

转载自blog.csdn.net/weixin_44223646/article/details/104304000