题目大意:

输入w h,接下来输入h行w列的图

':干净的点;  ' * ' :垃圾;  ' ' : 墙;  ' ' : 初始位置;

输出 清理掉所有垃圾的最短路径长度 无则输出-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;
}
View Code

状压 BFS 

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-06-27
  • 2021-12-04
  • 2021-11-23
  • 2022-12-23
猜你喜欢
  • 2021-06-11
  • 2021-07-09
  • 2021-11-19
  • 2021-08-12
  • 2022-12-23
  • 2022-12-23
  • 2021-12-11
相关资源
相似解决方案