题意:从地图上一个点出发, 要求总共到达四个点, 求最短行驶距离。
很明显是一道广搜题, 要求经过4个点,
考虑到点数不多, 可枚举所有的经过顺序 (4! = 24), 接下来便是简单广搜了。
Tips:
枚举所有情况 可以用 next_permutation 函数, 用法见代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const double inf = 1e9;
const double eps = 1e-7;
const int maxn = 111111;
int book[maxn];
typedef struct{
int x;
int y;
int cnt;
}node;
node nod[11];
char mapc[111][111];
int mapp[111][111];
int dir[4][2] = {1,0, -1,0, 0,1, 0,-1};
int bfs(int x1, int y1, int x2, int y2){
memset(mapp, 0, sizeof(mapp));
node st, cur, pre;
queue<node>q;
st.x = x1, st.y = y1, st.cnt = 0;
mapp[x1][y1] = 1;
q.push(st);
while(!q.empty()){
pre = q.front();
q.pop();
if(pre.x == x2 && pre.y == y2) return pre.cnt;
for(int i=0; i<4; i++){
cur.x = pre.x + dir[i][0];
cur.y = pre.y + dir[i][1];
cur.cnt = pre.cnt + 1;
if(mapp[cur.x][cur.y] == 1 || mapc[cur.x][cur.y] == '#')
continue;
q.push(cur);
mapp[cur.x][cur.y] = 1;
}
}
return inf/4;
}
int main(){
int n,m,i,j,k;
int book[11][11];
while(cin>>n>>m && (n||m)){
for(i=0; i<=n+1; i++)
for(j=0; j<=m+1; j++)
mapc[i][j] = '#';
for(i=1; i<=n; i++)
for(j=1; j<=m; j++){
cin>>mapc[i][j];
if(mapc[i][j] == '@'){
nod[0].x = i;
nod[0].y = j;
mapc[i][j] = '.';
}
}
cin>>k;
for(i=1; i<=k; i++)
cin>>nod[i].x>>nod[i].y;
memset(book, 0, sizeof(book));
for(i=0; i<=k; i++)
for(j=0; j<=k; j++)
book[i][j] = bfs(nod[i].x, nod[i].y, nod[j].x, nod[j].y);
int per[] = {1,2,3,4};
int minn = inf/4;
do{
int ans = book[0][per[0]];
for(i=0; i<k-1; i++)
ans += book[per[i]][per[i+1]];
minn = min(minn, ans);
}while(next_permutation(per, per+k));
if(minn == inf/4) cout<<-1<<endl;
else cout<<minn<<endl;
}
return 0;
}