题目:hdu4771
题意:寻找带有多个目的地的最短路
解答:因为一共最多有4个目的地。所以将四个目的地排序。然后依次求出该顺序的最短路。选择最短的即可。
注意:1、下标问题!
2、注意返回误解的情况。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<string>
const int MAXN = 110;
using namespace std;
char pic[MAXN][MAXN];
int vis[MAXN][MAXN];
int Endp[5][2];
int n,m,startx,starty,k;
int dir[4][2] = {0,1,1,0,0,-1,-1,0};
int perarr[5];
int ans = 1 << 30;
struct node
{
int x,y,t;
};
queue<node> q;
int bfs(int a,int b,int c,int d)
{
bool flag = false;
int x,y,t;
node tmp;
tmp.x = a;
tmp.y = b;
tmp.t = 0;
vis[a][b] = 1;
q.push(tmp);
while(!q.empty())
{
node tmp = q.front();
x = tmp.x;
y = tmp.y;
t = tmp.t;
q.pop();
for(int i = 0;i < 4;i++)
{
int tx = x + dir[i][0];
int ty = y + dir[i][1];
if(!vis[tx][ty] && tx >= 0 && ty >= 0 && tx < n && ty < m && pic[tx][ty]!= '#')
{
if(tx == c && ty == d)
{
flag = true;
return t+1;
}
vis[tx][ty] = 1;
node tmp;
tmp.x = tx;
tmp.y = ty;
tmp.t = t+1;
q.push(tmp);
}
}
}
if(!flag)
return -1;
}
void cal()
{
sort(perarr,perarr+k);
do
{
memset(vis,0,sizeof(vis));
while(!q.empty())
q.pop();
int sum = bfs(startx,starty,Endp[perarr[0]][0],Endp[perarr[0]][1]);
if(sum == -1)
{
ans = -1;
return;
}
if(k > 1)
{
for(int i = 0;i < k-1;i++)
{
memset(vis,0,sizeof(vis));
while(!q.empty())
q.pop();
int tt = bfs(Endp[perarr[i]][0],Endp[perarr[i]][1],Endp[perarr[i+1]][0],Endp[perarr[i+1]][1]);
if(tt == -1)
{
ans = -1;
return;
}
sum += tt;
}
}
ans = min(ans,sum);
}while(next_permutation(perarr,perarr+k));
}
int main()
{
while(~scanf("%d%d",&n,&m)){
ans = 1 << 30;
if(n == 0 && m == 0)
break;
for(int i = 0;i < n;i++)
scanf("%s",pic[i]);
for(int i = 0;i < n;i++)
for(int j = 0;j < m;j++)
if(pic[i][j] == '@')
{
startx = i;
starty = j;
}
scanf("%d",&k);
for(int i = 1;i <= k;i++)
{
int buf1,buf2;
scanf("%d%d",&buf1,&buf2);
Endp[i][0] = buf1-1;
Endp[i][1] = buf2-1;
}
for(int i = 0;i < k;i++)
perarr[i] = i+1;
cal();
printf("%d\n",ans);
}
return 0;
}