廣搜水題_Poj_3984

//該題主要是學會任何在廣搜的過程中,記錄下最短的那條路徑
//方法:隊列中的任何一個節點的前驅節點唯一,利用這一點,記錄下前驅節點並深搜輸出


#include<iostream>
#include<queue>
using namespace std;

//定義節點
struct Node
{
int value;
int x,y;
int pre_x,pre_y;//前驅節點。因爲後繼節點可能多個,但前驅節點唯一
bool sign;
}node[5][5];

//定義隊列
queue<Node>Q;

//定義四個方向的想,x和y的變化
int go_x[4]={-1,0,1,0};
int go_y[4]={0,1,0,-1};

//判斷是否在圖內
bool IsIn(int x,int y)
{
if(x<0||x>4||y<0||y>4) return false;
else return true;
}

//廣搜,搜索最短路
void bfs()
{
int now_x,now_y,i,tx,ty;
now_x=Q.front().x,now_y=Q.front().y;
for(i=0;i<4;i++)
{
tx=now_x+go_x[i],ty=now_y+go_y[i];
if(IsIn(tx,ty) && !node[tx][ty].sign && node[tx][ty].value!=1)
{
node[tx][ty].pre_x=now_x;
node[tx][ty].pre_y=now_y;
node[tx][ty].sign=true;
Q.push(node[tx][ty]);
}
}
Q.pop();
while(!Q.empty())
{
now_x=Q.front().x,now_y=Q.front().y;
if(now_x==4 && now_y==4) return;//如果已經到達重點則返回
for(i=0;i<4;i++)
{
tx=now_x+go_x[i],ty=now_y+go_y[i];
if(IsIn(tx,ty) && !node[tx][ty].sign && node[tx][ty].value!=1)
{
node[tx][ty].pre_x=now_x;
node[tx][ty].pre_y=now_y;
node[tx][ty].sign=true;
Q.push(node[tx][ty]);
}
}
Q.pop();
}
}

//深搜,搜索一路走來的路徑
void dfs(int x,int y)
{
int pre_x=node[x][y].pre_x;
int pre_y=node[x][y].pre_y;
//如果有祖先,則搜索祖先
if(pre_x!=-1 && pre_y!=-1)
dfs(pre_x,pre_y);
//輸出自己的地址,無論是否有祖先(隊列中無祖先的只有【0】【0】點)
printf("(%d, %d)\n",x,y);
}

int main()
{
int i,j;
while(cin>>node[0][0].value)
{
//讀入數據
for(i=1;i<5;i++)
cin>>node[0][i].value;
for(i=1;i<5;i++)
{
for(j=0;j<5;j++)
  cin>>node[i][j].value;
}
//初始化節點的其他數據
for(i=0;i<5;i++)
{
for(j=0;j<5;j++)
{
node[i][j].pre_x=node[i][j].pre_y=-1;
node[i][j].x=i;
node[i][j].y=j;
node[i][j].sign=false;
}
}
//清空隊列
while(!Q.empty())
Q.pop();


node[0][0].sign=true;
Q.push(node[0][0]);
// 搜索最短路徑
bfs();
// 輸出路徑
dfs(4,4);
}
return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章