题意:给出一个图,求出经过所有给定点(<=4个)的最短路径。
题解:由于给定点很少,可以进行状态压缩,然后包里搜索即可。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;
const int maxn = 100+10;
const int INF = 1e9+7;
int n,m,p;
int dp[maxn][maxn][1 << 4];
int mustmap[maxn][maxn];
struct Point {
int row;
int col;
Point operator = (const Point &b) {
row = b.row;
col = b.col;
return *this;
}
};
Point must[maxn];
Point from;
struct HeapNode{
Point a;
int st;
int step;
};
char map1[maxn][maxn];
char c;
int dx[] = {0,0,-1,1};
int dy[] = {1,-1,0,0};
queue<HeapNode> q;
void bfs(Point from ){
HeapNode now;
now.a = from;now.st=0;now.step = 0;
q.push(now);
while(!q.empty()){
HeapNode ne = q.front();q.pop();
Point np = ne.a;
int nr = np.row;
int nc = np.col;
int nstep = ne.step;
for(int i=0;i<4;i++){
int nowr= nr + dx[i];
int nowc = nc + dy[i];
int nowst = ne.st;
if(nowr<=0 || nowr >n || nowc<=0 || nowc >m ) continue;
if(map1[nowr][nowc] == '#') continue;
if(mustmap[nowr][nowc] > 0) {//printf("nowr: %d nowc: %d\n",nowr,nowc);
int temp = mustmap[nowr][nowc];
if(nowst & (1 << (temp-1)));
else nowst ^= (1 << (temp-1));
}
if(dp[nowr][nowc][nowst] == -1) {
dp[nowr][nowc][nowst] = nstep + 1;
q.push((HeapNode){(Point){nowr,nowc},nowst,nstep+1});
}
}
}
}
int main()
{
freopen("G.in","r",stdin);
freopen("G.out","w",stdout);
while(~scanf("%d%d",&n,&m) && n){//printf("1\n");
memset(mustmap,0,sizeof(mustmap));
memset(dp,-1,sizeof(dp));
scanf("%c",&c);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++) {
scanf("%c",&map1[i][j]);
if(map1[i][j] == '@') {from.row = i;from.col = j;}
}
scanf("%c",&c);
}
scanf("%d",&p);
for(int i=1;i<=p;i++) {
scanf("%d%d",&must[i].row,&must[i].col);
mustmap[must[i].row][must[i].col] = i;
}
bfs(from);
int ans = INF;
for(int i=1;i<=p;i++) {
Point &e = must[i];
if(dp[e.row][e.col][(1 << p) - 1] != -1)
ans = min(ans,dp[e.row][e.col][(1 << p) - 1]);
}
if(ans == INF) ans = -1;
printf("%d\n",ans);
}
return 0;
}