分析:
给出一个N×M的方格,方格由不可走的 ‘#’ 和可以通过的 ‘.’组成,给出起始点’@’和K个宝藏的坐标,求从起始点出发拿到所有宝藏的最短路径。题解:
我们先通过BFS求出任意两点间的最短距离,如果某两点间走不通就直接跳出输出-1,求完距离之后我们可以通过DFS暴力搜索每一种走法的总长度,然后取最短的那一种即可。BFS求两点间最短距离:
int dir[][2] = {{-1,0},{0,1},{1,0},{0,-1}};
int check(int x,int y)
{
if(x<1 || y<1 || x>M || y>N || Map[x][y]==-1 )
return 0;
return 1;
}
int BFS(int s,int t)//从s到t的最短距离
{
memset(vis,0,sizeof(vis));
queue<node> q;
node var;
var.x = P[s].x;
var.y = P[s].y;
var.step = 0;
q.push(var); //把起始点放进队列
vis[var.x][var.y] = 1; //标记
while(!q.empty())
{
var = q.front();
q.pop();
if(var.x==P[t].x && var.y==P[t].y) //如果抵达终点
return var.step; //返回距离(步数)
for(int k=0;k<4;k++)
{
int xx = var.x+dir[k][0];
int yy = var.y+dir[k][1];
if(check(xx,yy) && vis[xx][yy]==0) //检查该点是否能走或是否走过
{
node var1;
vis[xx][yy] = 1;
var1.x = xx;
var1.y = yy;
var1.step = var.step+1;
q.push(var1);
}
}
}
return -1;
}
- DFS 暴搜所有路径
void DFS(int f[], int pre, int sum, int mm) //f[]为标记数组,pre为当前点,sum 为总长,mm为走过的总点数
{
if(mm==K)
{
if(ans>sum) //取总长最小的距离
ans = sum;
}
for(int i=1;i<=K;i++)
{
if(f[i]==0)
{
f[i] = 1; //标记
DFS(f, i,sum+dist[pre][i],mm+1);
f[i] = 0; //复原
}
}
- AC代码:
/*************************************************************************
> File Name: G.cpp
> Author: Akira
> Mail: qaq.febr2.qaq@gmail.com
> Created Time: 2016年08月20日 星期六 18时39分20秒
************************************************************************/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cmath>
#include <vector>
#include <set>
#include <list>
#include <ctime>
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;
#define MST(a,b) memset(a,b,sizeof(a))
#define CLR(a) MST(a,0)
#define Sqr(a) ((a)*(a))
using namespace std;
#define MaxN 100000
#define MaxM MaxN*10
#define INF 1000000000
#define bug cout<<88888888<<endl;
int Map[110][110];
int N,M;
int Sx,Sy;
int K;
int dir[][2] = {{-1,0},{0,1},{1,0},{0,-1}};
int dist[10][10];
struct node
{
int x,y,step;
}P[6];
int check(int x,int y)
{
if(x<1 || y<1 || x>M || y>N || Map[x][y]==-1 )
return 0;
return 1;
}
int vis[105][105];
int BFS(int s,int t)
{
memset(vis,0,sizeof(vis));
queue<node> q;
node var;
var.x = P[s].x;
var.y = P[s].y;
var.step = 0;
q.push(var);
vis[var.x][var.y] = 1;
while(!q.empty())
{
var = q.front();
q.pop();
if(var.x==P[t].x && var.y==P[t].y)
return var.step;
for(int k=0;k<4;k++)
{
int xx = var.x+dir[k][0];
int yy = var.y+dir[k][1];
if(check(xx,yy) && vis[xx][yy]==0)
{
node var1;
vis[xx][yy] = 1;
var1.x = xx;
var1.y = yy;
var1.step = var.step+1;
q.push(var1);
}
}
}
return -1;
}
int ans;
void DFS(int f[], int pre, int sum, int mm)
{
if(mm==K)
{
if(ans>sum)
ans = sum;
}
for(int i=1;i<=K;i++)
{
if(f[i]==0)
{
f[i] = 1;
DFS(f, i,sum+dist[pre][i],mm+1);
f[i] = 0;
}
}
}
int main()
{
while(cin >> N >> M && (N+M))
{
for(int i=1;i<=N;i++)
{
getchar();
for(int j=1;j<=M;j++)
{
char ch;
ch = getchar();
int num;
if(ch == '#') num = -1;
else if(ch == '.') num = 0;
else
{
Sx = i;
Sy = j;
num = 0;
}
Map[i][j] = num;
}
}
cin >> K;
P[0].x = Sx;
P[0].y = Sy;
for(int i=1;i<=K;i++)
{
int a,b;
cin >> a >> b;
P[i].x = a;
P[i].y = b;
}
memset(dist, -1, sizeof(dist));
int flag = 0;
for(int i=0;i<=K;i++)
{
dist[i][i] = 0;
for(int j=0;j<=K;j++)
{
if(dist[i][j] == -1)
{
int tmp = BFS(i, j);
dist[i][j] = dist[j][i] = tmp;
if(tmp == -1)
{
flag = 1;
break;
}
}
}
if(flag) break;
}
if(flag)
{
cout << -1 << endl;
}
else
{
int f[10];
ans = 100009;
CLR(f);
DFS(f,0,0,0);
printf("%d\n",ans);
}
}
return 0;
}