1. 程式人生 > >Find a way (廣度優先搜索)

Find a way (廣度優先搜索)

需要 sam namespace 比較 建立 繼續 tip total lag

題目:

Pass a year learning in Hangzhou, yifenfei arrival hometown Ningbo at finally. Leave Ningbo one year, yifenfei have many people to meet. Especially a good friend Merceki.
Yifenfei’s home is at the countryside, but Merceki’s home is in the center of city. So yifenfei made arrangements with Merceki to meet at a KFC. There are many KFC in Ningbo, they want to choose one that let the total time to it be most smallest.


Now give you a Ningbo map, Both yifenfei and Merceki can move up, down ,left, right to the adjacent road by cost 11 minutes.
InputThe input contains multiple test cases.
Each test case include, first two integers n, m. (2<=n,m<=200).
Next n lines, each line included m character.
‘Y’ express yifenfei initial position.

‘M’ express Merceki initial position.
‘#’ forbid road;
‘.’ Road.
[email protected] KCF


Output

For each test case output the minimum total time that both yifenfei and Merceki to arrival one of KFC.You may sure there is always have a KFC that can let them meet.

Sample Input

4 4
Y.#@
....
.#..
@..M
4 4
Y.#@
....
.#..
@#.M
5 5
Y..@.
.#...
.#...
@..M.
#...#

Sample Output

66
88
66

題意:題意大概是在一幅地圖上面,一直兩個人的位置,求這兩個人到KFC的最小距離之和,最後乘以11得到所用最小時間和
([email protected],墻用‘#’表示,兩個人分別為M和Y,‘.’表示能通過)

分析:分別求用bfs求兩個人到KFC的最短距離,(我將maxi設置成的40050,因為m<=200,n>=2,我用的40050AC了),將每一條
KFC的距離進行比較得出最短距離
AC代碼:

#include<iostream>
#include<queue>
#include<string.h>
#include<string>
using namespace std;
struct knot
{
int x,y; //結點的橫縱坐標
int t; //到達當前結點所走的步數
};
knot ai,temp;


int s1[205][205]; //判斷所在結點是否為遍歷過
int n,m; //地圖大小
int s2[2][205][205];
int flag[4][2]={1,0,-1,0,0,1,0,-1}; //用於移動的方向
char a[205][205];
int mini(int a,int b)
{
return a>b?b:a;
}
void bfs(int ix,int iy,int ik) //廣度優先查找
{
queue<knot>s; //建立一個裝knot的隊列
temp.x=ix; //temp作為中間變量,即主函數中需要查找的點
temp.y=iy;
temp.t=0; //移動步數初始化為0;
s.push(temp);
while (!s.empty())
{
ai=s.front();
s.pop();
temp.t=ai.t+1; //移動步數加1
for (int i=0;i<4;i++)
{
temp.x=ai.x+flag[i][0]; //移動x坐標
temp.y=ai.y+flag[i][1]; //移動y坐標
if (temp.x>=0&&temp.x<n&&temp.y>=0&&temp.y<m&&s1[temp.x][temp.y]==0&&a[temp.x][temp.y]!=‘#‘)

//判斷還能不能朝著同一個方向繼續前行
{
if (a[temp.x][temp.y][email protected])
s2[ik][temp.x][temp.y]=temp.t;
s1[temp.x][temp.y]=1;
s.push(temp);
}
}


}
}
int main()
{


int xm,ym,xy,yy;


while (cin>>n>>m)
{


for (int i=0;i<n;i++)
{
for (int j=0;j<m;j++)
{ cin>>a[i][j];
if (a[i][j]==‘M‘) //確定M所在位置的坐標
xm=i,ym=j;
if (a[i][j]==‘Y‘) //確定Y所在位置的坐標
xy=i,yy=j;
}


}
int maxi=1000000; //註意maxi初始化的位置,在輸入一組地圖以後maxi會發生改變
memset(s1,0,sizeof(s1));
memset(s2,0,sizeof(s2));
s1[xm][ym]=1;
bfs(xm,ym,1);
memset(s1,0,sizeof(s1));

//在第一次進行bfs時,s1數據發生改變,因此在第二次bfs前需要清零;memset的頭文件為#include<cstring>
s1[xy][yy]=1;
bfs(xy,yy,2);
for (int i=0;i<n;i++)
for (int j=0;j<m;j++)
if (s2[1][i][j]&&s2[2][i][j])
maxi=mini(maxi,s2[1][i][j]+s2[2][i][j]); //求最小距離
cout << maxi*11 << endl; //每一步需要11分鐘
}
return 0;
}




Find a way (廣度優先搜索)