题目大意:
输入w h,接下来输入h行w列的图
' . ':干净的点; ' * ' :垃圾; ' x ' : 墙; ' o ' : 初始位置;
输出 清理掉所有垃圾的最短路径长度 无则输出-1
Sample Input
7 5
.......
.o...*.
.......
.*...*.
.......
15 13
.......x.......
...o...x....*..
.......x.......
.......x.......
.......x.......
...............
xxxxx.....xxxxx
...............
.......x.......
.......x.......
.......x.......
..*....x....*..
.......x.......
10 10
..........
..o.......
..........
..........
..........
.....xxxxx
.....x....
.....x.*..
.....x....
.....x....
0 0
Sample Output
8
49
-1
题解
用bfs求出任意两点间的距离然后转换成tsp问题,用dfs解
/* 题意:给一个 n*m的图,有一个机器人从一点开始清理垃圾,要求把所有的垃圾清理完,求最短的路径 思路:这个题可以先用bfs求出任意两点间的距离然后转换成tsp问题,用dfs解。 这个题还可以用状态压缩bfs写,但写了一次没过,再试试。 */ #include <cstdlib> #include <stdio.h> #include <string.h> #include <queue> #define INF 0x7fffffff #define N 22 using namespace std; struct node { int x,y,step; }p[N*N],s,e; char map[N][N]; int n,m,d[4][2]={0,1,1,0,0,-1,-1,0},used[N][N]; int dis[N][N],ans,use[N],cnt; bool ok(int x,int y) { return x>=0&&x<n&&y>=0&&y<m&&map[x][y]!='x'&&!used[x][y]; } int bfs() { memset(used,0,sizeof(used)); int i; queue<node> q; q.push(s); while(!q.empty()) { node cur=q.front(),next; q.pop(); for(i=0;i<4;i++) { next.x=cur.x+d[i][0]; next.y=cur.y+d[i][1]; next.step=cur.step+1; if(ok(next.x,next.y)) { used[next.x][next.y]=1; if(next.x==e.x&&next.y==e.y) return next.step; q.push(next); } } } return INF; } void dfs(int s,int num,int length) { int j; if(num==0&&ans>length) { ans=length; return ; } if(length>ans) return ; for(j=0;j<cnt;j++) { if(dis[s][j]!=INF&&!use[j]) { use[j]=1; length+=dis[s][j]; dfs(j,num-1,length); num+1; length-=dis[s][j]; use[j]=0; } } } int main() { int i, j, start, flag; while(scanf("%d%d",&m,&n)&&(n||m)) { cnt=flag=0; for(i=0;i<n;i++) { scanf("%s",map[i]); for(j=0;j<m;j++) { if(map[i][j]=='o'||map[i][j]=='*') { p[cnt].x=i,p[cnt].y=j; if(map[i][j]=='o') start=cnt; cnt++; } dis[i][j]=INF; } } //memset(dis,INF,sizeof(dis)); for(i=0;i<cnt;i++) for(j=i+1;j<cnt;j++) { s=p[i],e=p[j],s.step=0; dis[i][j]=dis[j][i]=bfs(); if(dis[i][j]==INF) { flag=1; break; } } /* for(i=0;i<cnt;i++) { for(j=0;j<cnt;j++) printf("%d\t",dis[i][j]); puts(""); }*/ if(flag) puts("-1"); else { ans=INF; memset(use,0,sizeof(use)); use[start]=1; dfs(start,cnt-1,0); printf("%d\n",ans); } } return 0; }
状压 BFS