题意:给一个n*m的矩阵,机器人的位于某点,问机器人把所以垃圾清理的最短路。
据说的是tsp问题,但不也不懂。。。不过这题还是让我练习了一下dfs,bfs,虽然还是不怎么会。。
首先用dfs求出机器人和任意垃圾的最短距离(刚开始的时候写网上的代码的时候不是很好理解,因为逻辑性比较强,而我反应慢,而且逻辑性差,所以看了好久,后来看学校其他人的代码的时候就容易理解了;
网上:首先求出机器人和垃圾的位置,并且标号,然后用bfs求出每个点和其他点的最短距离
zhenhao:首先求出机器人和其他垃圾的最短距离,然后判断能否清理完所有的垃圾,然后在用另外的点去求出与其他点的最短距离,然后得出一个最短距离dis[][])
然后再用dfs求出最短距离,好像还可以用状压去求,可是感觉好麻烦,而且也不会~~
网上:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
//#include <time.h>
#include <queue>
using namespace std;
#define maxn 50
#define INF 10000000
char map[maxn][maxn];
int dist[maxn][maxn]; //距离
int cnt,w,h;
int tag[maxn][maxn];
struct point
{
int x,y,step;
}pos[maxn*maxn];
point robot;
int dir[4][2]={0,-1,0,1,-1,0,1,0};
bool isok(point p)
{
if(p.x<1||p.x>h||p.y<1||p.y>w)
return false;
return true;
}
bool visit[maxn][maxn];
void bfs(point p,int po)
{
visit[p.x][p.y]=1;
queue<point> q;
while(!q.empty())
q.pop();
q.push(p);
while(!q.empty())
{
point cur=q.front();
q.pop();
if(map[cur.x][cur.y]=='o'||map[cur.x][cur.y]=='*')
dist[po][tag[cur.x][cur.y]]=cur.step;
point next;
next.step=cur.step+1;
for(int i=0;i<4;i++)
{
next.x=cur.x+dir[i][0];
next.y=cur.y+dir[i][1];
if(!isok(next)||visit[next.x][next.y]||map[next.x][next.y]=='x')
continue;
q.push(next);
visit[next.x][next.y]=1;
}
}
}
int ans;
bool vis[maxn];
void dfs(int x,int step,int s)
{
if(step==cnt)
{
if(s<ans)
ans=s;
return ;
}
if(s>ans)
return ;
for(int i=1;i<=cnt;i++)
{
if(vis[i])
continue;
vis[i]=1;
dfs(i,step+1,s+dist[x][i]);
vis[i]=0;
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
while(~scanf("%d%d",&w,&h))
{
if(w+h==0)
break;
getchar();
cnt=0;
memset(pos,0,sizeof(pos));
memset(tag,0,sizeof(tag));
for(int i=1;i<=h;i++)
{
gets(map[i]+1);
//cout<<(map[i]+1)<<endl;
for(int j=1;j<=w;j++)
{
if(map[i][j]=='o')
{
pos[++cnt].x=i;
pos[cnt].y=j;
robot.x=i;
robot.y=j;
tag[i][j]=cnt; //点
}
else if(map[i][j]=='*')
{
pos[++cnt].x=i;
pos[cnt].y=j;
tag[i][j]=cnt;
}
}
}
for(int i=1;i<=cnt;i++)
{
for(int j=1;j<=cnt;j++)
if(i!=j)
dist[i][j]=INF;
else
dist[i][j]=0;
}
for(int i=1;i<=cnt;i++)
{
memset(visit,0,sizeof(visit));
pos[i].step=0;
bfs(pos[i],i);
}
bool flag=1;
for(int i=1;i<=cnt&&flag;i++)
{
for(int j=1;j<=cnt&&flag;j++)
if(dist[i][j]==INF)
flag=0;
}
if(flag==0)
{
puts("-1");
continue;
}
memset(vis,0,sizeof(vis));
vis[tag[robot.x][robot.y]]=1;
ans=INF;
dfs(tag[robot.x][robot.y],1,0);
printf("%d\n",ans);
}
}
zhenhao:
http://acm.hust.edu.cn/vjudge/contest/viewSource.action?id=5751585
passkey:sweetz0327