来自xjy的签到题
 

Description

爱丽丝冒险来到了红皇后一个n*n大小的花园,每个格子由'.'或'#'表示,'.'表示爱丽丝可以到达这个格子,‘#’表示爱丽丝不能到达这个格子,爱丽丝每1分钟可以移动到非'#'的相邻格子(与当前所在格子具有公共边)。花园下面有m个隧道,每个隧道有一个出口和一个入口。当爱丽丝到达隧道的入口时,她可以选择(也可以不选择)进入隧道入口,并通过隧道一次,然后立即(不花费时间)出现在隧道出口。爱丽丝一开始可以降临在花园的任何地方。有好奇心的爱丽丝想知道,她通过所有隧道且每个隧道仅通过一次最少需要花费多少时间。(注意,爱丽丝不能从隧道出口通往隧道入口)

Input

输入包含多个测试用例,不超过10组。对于每个测试用例,第一行输入n(1<=n<=15)和m(1<=m<=15),分别表示地图的大小为n*n和m个隧道。然后给出一个n行n列的花园地图,由'.'或'#'组成,'.'表示爱丽丝可以到达这个格子,‘#’表示爱丽丝不能到达这个格子。接下来m行,表示m个隧道。每行四个正整数x1,y1,x2,y2(1<=x1,x2,y1,y2<=15),表示隧道的入口为(x1,y1),出口为(x2,y2)。数据保证隧道入口和出口位置不会出现在‘#’上。

Output

对于每个测试用例,你需要输出一个整数,表示爱丽丝通过所有隧道仅一次的最少时间。如果爱丽丝无法通过所有隧道,则输出-1。

Sample Input 1

5 4
....#
...#.
.....
.....
.....
2 3 1 4
1 2 3 5
2 3 3 1
5 4 2 1

Sample Output 1

7

Hint

对于样例,爱丽丝可以一开始降临在(2,3)并穿过第一个隧道到达(1,4),然后花费2分钟走向(1,2)并穿过第二个隧道到达(3,5),然后花费3分钟走向(5,4)并穿过第四个隧道到达(2,1),最后花费2分钟走向(2,3)并穿过第三个隧道到达(3,1)。至此通过所有隧道,并花费7分钟时间。

注意本题时间限制和空间限制

将隧道视为点,先bfs预处理出两两隧道间的距离,然后使用状压dp求出最小时间。

转移方程:dp[目标状态][目标点]=min(dp[目标状态][目标点],dp[当前状态][当前点]+dis[当前点][目标点])。

#include<bits/stdc++.h>
#define MAX 16
#define INF 0x3f3f3f3f
using namespace std; char s[MAX][MAX];
int b[MAX][MAX],dis[MAX][MAX];
int dp[<<][MAX];
int t[][]={,,,,-,,,-};
struct Node{
int bx,by,ex,ey;
}a[MAX];
struct Node2{
int x,y,s;
}node;
queue<Node2> q; int bfs(Node u,Node v,int n){
memset(b,,sizeof(b));
while(q.size()){
q.pop();
}
if(u.ex==v.bx&&u.ey==v.by) return ;
node.x=u.ex;
node.y=u.ey;
node.s=;
q.push(node);
b[node.x][node.y]=;
while(q.size()){
for(int i=;i<;i++){
Node2 now=q.front();
int tx=now.x+t[i][];
int ty=now.y+t[i][];
if(tx<||tx>n||ty<||ty>n) continue;
if(s[tx][ty]=='#'||b[tx][ty]==) continue;
b[tx][ty]=;
if(tx==v.bx&&ty==v.by){
return now.s+;
}
node.x=tx;
node.y=ty;
node.s=now.s+;
q.push(node);
}
q.pop();
}
return INF;
}
int main()
{
int n,m,i,j,k;
while(~scanf("%d%d",&n,&m)){
for(i=;i<=n;i++){
scanf(" %s",s[i]+);
}
for(i=;i<=m;i++){
scanf("%d%d%d%d",&a[i].bx,&a[i].by,&a[i].ex,&a[i].ey);
}
memset(dis,INF,sizeof(dis));
for(i=;i<=m;i++){
for(j=;j<=m;j++){
if(i==j) continue;
dis[i][j]=bfs(a[i],a[j],n);
}
}
memset(dp,INF,sizeof(dp));
for(i=;i<=m;i++){
dp[<<(i-)][i]=;
}
for(i=;i<(<<m);i++){
for(j=;j<=m;j++){
if(!(i&(<<(j-)))) continue;
for(k=;k<=m;k++){
if(j==k||dis[j][k]==INF||!(i&(<<(k-)))) continue;
dp[i][k]=min(dp[i][k],dp[i^(<<(k-))][j]+dis[j][k]);
}
}
}
int ans=INF;
for(i=;i<=m;i++){
ans=min(ans,dp[(<<m)-][i]);
}
if(ans==INF) printf("-1\n");
else printf("%d\n",ans);
}
return ;
}

最新文章

  1. 这可能是史上最全的CSS自适应布局总结教程
  2. ABP模块化
  3. Sizzle选择器引擎介绍
  4. 完成卸载vs2010后再安装
  5. ERROR: “System.Web.Mvc.Controller.File(string, string, string)”是一个“方法”
  6. for 与 foreach 性能
  7. spark(一) build
  8. html类,id规范命名
  9. Maven第三篇【Maven术语、pom.xml介绍】
  10. 记录Javascript的数据方法参考
  11. asyncio异步IO——Streams详解
  12. ArcGIS Pro开发Web3D应用(4)——Portal发布三维没有“发布”选项解决
  13. 安装Oracle数据库心得
  14. 20165337学习基础和C语言基础调查
  15. 死磕安卓前序:MVP架构探究之旅—基础篇
  16. Alpha冲刺! Day10 - 砍柴
  17. linux环境下安装qt过程
  18. Version Control 版本控制
  19. GIT rebase讲解
  20. 深入理解JAVA虚拟机阅读笔记5——Java内存模型与线程

热门文章

  1. Double Check Locking 双检查锁机制
  2. 九度OJ 1028:继续畅通工程 (最小生成树)
  3. ridge regression 无惩罚,导致预测结果空间过大而无实用价值
  4. 转载 j2ee j2se j2me 区别,mvc 和ssh联系理解
  5. /etc/init.d/nginx
  6. 使用 eslint 和 editorconfig 规范代码
  7. luoguP3769 [CH弱省胡策R2]TATT
  8. BZOJ 3362 Navigation Nightmare
  9. 理解SQL原理,写出高效的SQL语句
  10. Contiki-Timer 概述