生活随笔
收集整理的這篇文章主要介紹了
BFS最短路打印路径
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
Problem Description
2020級(jí)的新生即將來(lái)USST報(bào)道了,學(xué)校規(guī)定報(bào)道地點(diǎn)定在了516號(hào)的老體育館。
現(xiàn)在為了方便新生報(bào)道,Wiki自我推薦為新生繪制一張校園地圖。地圖功能很簡(jiǎn)單:假設(shè)校園是一張二維的平面圖,大小為n × m,校園的建筑在地圖上用任意字符表示,如果遇到不能前行的障礙物則用字符N表示,設(shè)起點(diǎn)為S,報(bào)道點(diǎn)為G,請(qǐng)你幫助Wiki計(jì)算出最短的報(bào)道距離以及該條最短路徑上的點(diǎn)坐標(biāo)。
如果存在多條的最短報(bào)道路徑,輸出任意一條即可。(假設(shè)可以在地圖“上下左右”四個(gè)方向上行走,且必存在到達(dá)路線)
Input
第一行輸入兩個(gè)正整數(shù)n和m(2 <= n, m <= 100),表示地圖的大小
第二行開(kāi)始輸入n行m列的建筑物字符標(biāo)識(shí)(字符釋義見(jiàn)上述題面)
Output
輸出第一行一個(gè)正整數(shù)ans,表示從起點(diǎn)S到終點(diǎn)G的最短距離
第二行開(kāi)始輸出最短路徑經(jīng)過(guò)的建筑物坐標(biāo)(xi, yi),輸出一個(gè)換一行,起點(diǎn)和終點(diǎn)坐標(biāo)也要輸出!假設(shè)坐標(biāo)原點(diǎn)為(0, 0)
Sample Input:
3 3
S
..
NN
.
G
..
Sample Output:
6
0 0
0 1
0 2
1 2
2 2
2 1
2 0
分析
BFS,記錄路徑。
此處使用兩個(gè)數(shù)組px[dx][dy]=x和py[dx][dy]=y來(lái)記錄點(diǎn)(dx,dy)的前面一點(diǎn)(x,y).
#include<iostream>
#include<queue>
#include<cstring>using namespace std
;const int maxn
=200;int m
,n
,t1
,t2
,d1
,d2
;
char a
[maxn
][maxn
];
bool vis
[maxn
][maxn
];
int dis
[4][2]={1,0,0,1,-1,0,0,-1};int len
[maxn
][maxn
];
int px
[maxn
][maxn
],py
[maxn
][maxn
];queue
<pair
<int,int> > q
;void bfs(){q
.push(make_pair(t1
,t2
));vis
[t1
][t2
]=1;while(!q
.empty()){int x
=q
.front().first
;int y
=q
.front().second
;q
.pop();if(x
==d1
&&y
==d2
) return;for(int i
=0;i
<4;i
++){int dx
=x
+dis
[i
][0];int dy
=y
+dis
[i
][1];if(dx
>=0&&dx
<m
&&dy
>=0&&dy
<n
&&!vis
[dx
][dy
]&&a
[dx
][dy
]!='N'){if(len
[dx
][dy
]>len
[x
][y
]+1){len
[dx
][dy
]=len
[x
][y
]+1;q
.push(make_pair(dx
,dy
));vis
[dx
][dy
]=1;px
[dx
][dy
]=x
;py
[dx
][dy
]=y
;} }} }
}void print(int x
,int y
){if(x
!=-1&&y
!=-1){print(px
[x
][y
],py
[x
][y
]);if(x
==d1
&&y
==d2
) cout
<<x
<<" "<<y
;else cout
<<x
<<" "<<y
<<endl
;}}int main(){memset(len
,0x3f,sizeof(len
));memset(vis
,0,sizeof(vis
));memset(px
,-1,sizeof(px
));memset(py
,-1,sizeof(py
));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
]=='S')t1
=i
,t2
=j
;if(a
[i
][j
]=='G')d1
=i
,d2
=j
;}len
[t1
][t2
]=0;bfs(); cout
<<len
[d1
][d2
]<<endl
;print(d1
,d2
);}
遞歸打印的寫(xiě)法
從終點(diǎn)到起點(diǎn)print(d1,d2),由于棧的后進(jìn)先出特性,遞歸最后的先返回,于是正好是先返回起點(diǎn),依次到終點(diǎn)。
void print(int x
,int y
){if(x
!=-1&&y
!=-1){print(px
[x
][y
],py
[x
][y
]);if(x
==d1
&&y
==d2
) cout
<<x
<<" "<<y
;else cout
<<x
<<" "<<y
<<endl
;}}
總結(jié)
以上是生活随笔為你收集整理的BFS最短路打印路径的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。