1. 程式人生 > >廣度優先搜尋-最少轉機次數

廣度優先搜尋-最少轉機次數

        當你和家人一起去海南旅遊,可是你的城市並沒有直接到達海南的飛機,但是你已經蒐集了很多航班的資訊,現在你希望找到一種乘坐方式,使得轉機次數最少

如何解決呢?  

  假如你的城市在1號城市,海南在5號城市;現有如下關係:


如何求得1號城市到5號城市的最少轉機次數呢?此時就用到了本次講解的內容,廣度優先搜尋!

作圖的問題首先我們應該用鄰接矩陣或者二維陣列來存取頂點之間的關係。

廣度優先搜尋需要用佇列來儲存每次擴充套件的關係。

首先將1號城市入隊,通過1號城市我們可以擴展出2號和3號城市,2號城市又可以擴展出3號城市和4號城市。由於3號城市已經在佇列中,所以只需要將四號城市入隊。

接下來3號城市又可以擴充套件處4號城市和5號城市,因為4號城市已經在佇列中,所以只需要將5號城市入隊。此時已經找到5號城市,那麼演算法結束。


程式碼如下:

#include<stdio.h>
struct node{
	int x;//城市編號
	int s;//轉機次數 
}que[2501];

int main()
{
	int e[51][51]={0},book[51]={0};//儲存圖的關係與標誌陣列
	int head,tail;
	int i,j,n,m,a,b,cur,start,end,flag=0;
	scanf("%d%d%d%d",&n,&m,&start,&end);//n表示城市的數量,m表示關係,start表示開始城市,end表示目的城市
	//初始化二維矩陣
	for(i=1;i<=n;i++)
	{
	   for(j=1;j<=n;j++) 
	   if(i==j)
	   e[i][j]=0;//這是認為自己到自己的距離為0; 
	   else
	   e[i][j]=0x3f3f3f3f;//十六進位制,表示無窮大常量 
	} 
	//讀入城市之間的航班
	for(i=1;i<=m;i++)
	{
		scanf("%d%d",&a,&b);
		e[a][b]=1;//此處是無向圖是雙向的 
		e[b][a]=1;
	} 
	//初始化佇列
	head=1;
	tail=1; 
	//從start號城市出發,將start號城市加入佇列 
	que[tail].x=start;
	que[tail].s=0;
	tail++;
	book[start]=1;//標記start號城市已經在佇列中 
	//當佇列不為空的時候迴圈
	while(head<tail)
	{
		cur=que[head].x;//當佇列中首城市的編號
		for(j=1;j<=n;j++)//從1-n依次嘗試
	    {	//從城市cur到城市j是否有航班並且判斷城市j是否在佇列橫縱
			if(e[cur][j]!=0x3f3f3f3f && book[j]==0)
			{//滿足條件cur到城市j有航班並且城市j不在佇列中,則j入隊 
				que[tail].x=j;
				que[tail].s=que[head].s+1;//轉機次數+1 
			    tail++; 
			    book[j]=1;//改變標記,以防重用 
			}
			//到達目標城市停止擴充套件,退出迴圈 
			if(que[tail].x==end) 
			{
				flag=1;
				break; 
			} 
	    } 
	    if(flag==1)
	      break;
	    head++;//擴充套件結束後,head++才能繼續擴充套件 
	} 
	printf("%d\n",que[tail-1].s);//由於tail是指向佇列隊尾的下一個位置,所以減1 
	return 0;
} 
/*
5 7 1 5
1 2
1 3
2 3
2 4
3 4
3 5
4 5
*/