这道题让我们求一个地图上的各个点之间的最短路径说白了旅行商问题。

那么我们先用一个裸的BFS求出各个点之间的最短距离,然后我们再枚举各个点的全排列即可

这道题的细节很多,详见注释

上代码~

 #include<stdio.h>
#include<algorithm>
#include<queue>
using namespace std;
int d[][];int w;int h;
char map[][];bool vis[][];
int dx[]={,-,,};int dy[]={,,-,};
int res;
struct data
{
int x;int y;int step;
}n[],now;int cnt;
inline int s(int x,int y)//强制转换点坐标为点号
{
for(int i=;i<=cnt;i++)
if(n[i].x==x&&n[i].y==y)
return i;
return ;
}
queue <data> q;
int c[];
void clear()//因为每一个点都要bfs所以搜一次清空一次
{
while(!q.empty())
{
q.pop();
}
for(int i=;i<h;i++)
for(int j=;j<w;j++)
vis[i][j]=false;
return;
}
int main()
{
while()
{
res=0x3f3f3f3f;cnt=;//多组询问的时候记得赋变量初值
scanf("%d%d",&w,&h);
if(w==&&h==)break;
for(int i=;i<h;i++)
{
scanf("%s",map[i]);
for(int j=;j<w;j++)
{
if(map[i][j]=='*')
{
n[++cnt].x=i;n[cnt].y=j;
}
else if(map[i][j]=='o')
{
n[].x=i;n[].y=j;
}
}
}
for(int i=;i<=cnt;i++)//记得清空邻接矩阵
{
for(int j=;j<=cnt;j++)
{
d[i][j]=;
}
}
for(int i=;i<=cnt;i++)//裸的bfs
{
q.push(n[i]);
//printf("STARTFROM%d\n",i);
vis[n[i].x][n[i].y]=true;
int rep=cnt;
while(!q.empty())
{
now=q.front();q.pop();
int x=now.x;int y=now.y;
//printf("nowis(%d,%d)\n",x,y);
for(int k=;k<;k++)
{
if(x+dx[k]<||x+dx[k]>=h||y+dy[k]<||y+dy[k]>=w||
vis[x+dx[k]][y+dy[k]]||map[x+dx[k]][y+dy[k]]=='x')//地图中是小写的x
continue;
if(map[x+dx[k]][y+dy[k]]=='*'||map[x+dx[k]][y+dy[k]]=='o')
{
int t=s(x+dx[k],y+dy[k]);
//printf("REACH%d,DISis%d\n",t,now.step+1);
d[i][t]=now.step+;
d[t][i]=now.step+;
rep--;
if(rep==)goto nxt;
}
vis[x+dx[k]][y+dy[k]]=true;
data p;p.x=x+dx[k];p.y=y+dy[k];p.step=now.step+;
q.push(p);
}
}
nxt:;
clear();
}
for(int i=;i<=cnt;i++)
{
c[i]=i;
//printf("node%dis(%d,%d)\n",i,n[i].x,n[i].y);
}
int rep;
/*for(int i=0;i<=cnt;i++)
{
for(int j=0;j<=cnt;j++)
{
printf("%-3d",d[i][j]);
}
printf("\n");
}*/
do
{
rep=;
for(int i=;i<cnt;i++)
{
//printf("%-2d",c[i]);
if(d[c[i]][c[i+]]==)
{
printf("-1\n");goto ed;
}
rep+=d[c[i]][c[i+]];
}
//printf("%-2d",c[cnt]);
//printf("%-5d",rep);
if(res>rep)res=rep;
//printf("\n");
}while(next_permutation(c+,c+cnt+));//枚举全排列
printf("%d\n",res);
ed:;
}
return ;//拜拜程序~
}

Poj2688cleaningrobot的更多相关文章

随机推荐

  1. C# 更新控件四部曲,自定义的用户控件无法更新怎么办

    用户控件如果在其他的项目被引用,希望更新控件后,所引用的项目同步更新效果,一开始难免失败,特别是更换了控件所在的文件夹. 这个时候,四部曲来解决控件的更新. 1.运行一下控件的项目,使控件生成一下. ...

  2. 常用的字符串函数-S

    header('content-type:text/html;charset=utf-f'); /* $var=addslashes($_GET['username']);//转义表单提交内容中的引号 ...

  3. python cmd的各种实现方法及优劣

    Python_cmd的各种实现方法及优劣(subprocess.Popen, os.system和commands.getstatusoutput)   目前我使用到的python中执行cmd的方式有 ...

  4. MSBuild 命令参数

    Build a Visual Studio project or solution using MSBuild Command Line Arguments  常用命令行参数 详解: MSBuild ...

  5. 【译】如何编写“移动端优先”CSS

    原文链接:https://zellwk.com/blog/how-to-write-mobile-first-css/ 构建响应式网站是如今前端开发者的必备技能,当我们谈到响应式网站时,“移动端优先” ...

  6. WORD中引用活动文档元素

    要引用活动的段落.表格.域或其他文档元素,可使用 Selection 属性返回一个 Selection 对象.通过 Selection 对象,可访问选定内容中的所有段落或第一段.下列示例将边框应用于选 ...

  7. windows 环境下mysql 重置密码解决方案

    1.打开本地安装MySQL的安装目录,如:D:\software\mysql-5.7.20-winx64 进入bin目录,执行如下命令: mysqld -nt --skip-grant-tables ...

  8. dos2章

    讲FOR之前呢,咋先告诉各位新手朋友,如果你有什么命令不懂,直接在CMD下面输入: name /? 这样的格式来看系统给出的帮助文件,比如for /? 就会把FOR命令的帮助全部显示出来!当然许多菜鸟 ...

  9. 两种语言实现设计模式(C++和Java)(二:单例模式)

    本篇介绍单例模式,可以说是使用场景最频繁的设计模式了.可以根据实例的生成时间,分为饿汉模式和懒汉模式 懒汉模式:饿了肯定要饥不择食.所以在单例类定义的时候就进行实例化. 饿汉模式:故名思义,不到万不得 ...

  10. MySQLdb模块(数据库)

    安装 pip install mysqlclient 连接数据库 db = MySQLdb.connect(host="IP",port=端口,user="账号" ...