题意:给一个 n*m的图,有一个机器人从一点开始清理垃圾,要求把所有的垃圾清理完,求最短的路径 思路:这个题可以先用bfs求出任意两点间的距离然后转换成tsp问题,用dfs解。 这个题还可以用状态压缩bfs写,但写了一次没过,再试试。 /* * File: main.cpp * Author: mi * * Created on 2011年1月13日, 上午11:14 */ #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 argc, char** argv) { 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; }