Tunnels

http://acm.hdu.edu.cn/showproblem.php?pid=4856

Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Problem Description
Bob is travelling in Xi’an. He finds many secret tunnels beneath the city. In his eyes, the city is a grid. He can’t enter a grid with a barrier. In one minute, he can move into an adjacent grid with no barrier. Bob is full of curiosity and he wants to visit all of the secret tunnels beneath the city. To travel in a tunnel, he has to walk to the entrance of the tunnel and go out from the exit after a fabulous visit. He can choose where he starts and he will travel each of the tunnels once and only once. Now he wants to know, how long it will take him to visit all the tunnels (excluding the time when he is in the tunnels).
Input
The input contains mutiple testcases. Please process till EOF.
For each testcase, the first line contains two integers N (1 ≤ N ≤ 15), the side length of the square map and M (1 ≤ M ≤ 15), the number of tunnels.
The map of the city is given in the next N lines. Each line contains exactly N characters. Barrier is represented by “#” and empty grid is represented by “.”.
Then M lines follow. Each line consists of four integers x1, y1, x2, y2, indicating there is a tunnel with entrence in (x1, y1) and exit in (x2, y2). It’s guaranteed that (x1, y1) and (x2, y2) in the map are both empty grid.
Output
For each case, output a integer indicating the minimal time Bob will use in total to walk between tunnels.
If it is impossible for Bob to visit all the tunnels, output -1.
Sample Input
5 4 ....# ...#. ..... ..... ..... 2 3 1 4 1 2 3 5 2 3 3 1 5 4 2 1
Sample Output
7

题目大意:给定一个n*n的格子,'.'代表可以走,'#'代表不可以走,每分钟可以往相邻的格子走,又存起点和终点已知的m条隧道,可以从任意一点开始,求经过所有隧道所用的最短时间?

大致思路:先bfs预处理出任意两点的最短路,然后就转换为TSP问题,由于必经的隧道很小,所以可以用状压DP

设dp[i][j]表示当前i中二进制中为1的位已经走过,且最后一个走过的隧道为第j条隧道

【注意】必须把表示走过的某些隧道这个状态放在最外层,把隧道放在最内层,WA在这2.5h,还是不太熟悉状压DP

只有这样才能保证当前使用的状态是最优状态,否则就限定了部分遍历隧道的顺序

①若未遍历的隧道在最外层,则限定了最后一个必定经过第m-1条隧道

②若已遍历的隧道在最外层,则限定了倒数第二个必定经过第m-1条隧道

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>using namespace std;struct Node {int r,c,t;Node(int rr=0,int cc=0,int tt=0):r(rr),c(cc),t(tt) {}
}u;struct Tunnel {int sr,sc,er,ec;
}tun[17];char city[17][17];
int n,m,rr,cc,mx;
int time[17][17][17][17];
bool vis[17][17];
int dp[(1<<15)+5][17];const int dr[4]={-1,0,1,0};
const int dc[4]={0,1,0,-1};inline bool isInside(int r,int c) {return 1<=r&&r<=n&&1<=c&&c<=n;
}void bfs(int r,int c) {queue<Node> q;q.push(Node(r,c,0));memset(vis,false,sizeof(vis));vis[r][c]=true;while(!q.empty()) {u=q.front();q.pop();time[r][c][u.r][u.c]=u.t;for(int i=0;i<4;++i) {rr=u.r+dr[i];cc=u.c+dc[i];if(isInside(rr,cc)&&city[rr][cc]!='#'&&!vis[rr][cc]) {vis[rr][cc]=true;q.push(Node(rr,cc,u.t+1));}}}
}int main() {while(2==scanf("%d%d",&n,&m)) {mx=1<<m;for(int i=1;i<=n;++i) {scanf("%s",&city[i][1]);}memset(time,0x3f,sizeof(time));memset(dp,0x3f,sizeof(dp));for(int i=0;i<m;++i) {scanf("%d%d%d%d",&tun[i].sr,&tun[i].sc,&tun[i].er,&tun[i].ec);bfs(tun[i].er,tun[i].ec);dp[1<<i][i]=0;}for(int j=0;j<mx;++j) {for(int i=0;i<m;++i) {if((j&(1<<i))==0) {//如果当前状态的第i条隧道未走过for(int k=0;k<m;++k) {if(dp[j][k]!=0x3f3f3f3f) {//如果当前状态的第k条隧道已走过dp[j|(1<<i)][i]=min(dp[j|(1<<i)][i],dp[j][k]+time[tun[k].er][tun[k].ec][tun[i].sr][tun[i].sc]);}}}}}int ans=0x3f3f3f3f;for(int i=0;i<m;++i) {ans=min(ans,dp[mx-1][i]);}printf("%d\n",ans==0x3f3f3f3f?-1:ans);}return 0;
}

HDU-4856 Tunnels(BFS状压DP)相关推荐

  1. Tunnels HDU - 4856 (bfs状压dp)

    Tunnels HDU - 4856 Bob is travelling in Xi'an. He finds many secret tunnels beneath the city. In his ...

  2. Hdu 4856 Tunnels(状压dp)

    题目链接 Tunnels Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tot ...

  3. HDU - 4856 Tunnels(哈密顿路径+状压dp)

    题目链接:点击查看 题目大意:给出一个n*n的正方形网格,其中"."表示可以走的路,"#"表示障碍物,每次可以向上下左右任意方向走1格,花费1单位时间,再给出m ...

  4. HDU 3001 三进制状压DP

    HDU 3001 三进制状压DP N个城市,M条道路,每条道路有其经过的代价,每一个城市最多能够到达两次,求走全然部城市最小代价,起点随意. 三进制状压.存储每一个状态下每一个城市经过的次数. 转移方 ...

  5. HDU 4856 Tunnels(BFS+状压DP)

    HDU 4856 Tunnels 题目链接 题意:给定一些管道.然后管道之间走是不用时间的,陆地上有障碍.陆地上走一步花费时间1,求遍历全部管道须要的最短时间.每一个管道仅仅能走一次 思路:先BFS预 ...

  6. hdu 4778 Gems Fight! 状压dp

    转自wdd :http://blog.csdn.net/u010535824/article/details/38540835 题目链接:hdu 4778 状压DP 用DP[i]表示从i状态选到结束得 ...

  7. QDUOJ 来自xjy的签到题(bfs+状压dp)

    来自xjy的签到题 Description 爱丽丝冒险来到了红皇后一个n*n大小的花园,每个格子由'.'或'#'表示,'.'表示爱丽丝可以到达这个格子,'#'表示爱丽丝不能到达这个格子,爱丽丝每1分钟 ...

  8. HDU4856:Tunnels (BFS 状压dp)

    Bob is travelling in Xi'an. He finds many secret tunnels beneath the city. In his eyes, the city is ...

  9. hdu 4568 bfs + 状压dp

    //这题的数据是不是有问题... 不考虑宝藏一个也拿不到也能AC... 1 #include "bits/stdc++.h" 2 using namespace std; 3 co ...

最新文章

  1. 冒泡链表排序java_链表排序(冒泡、选择、插入、快排、归并、希尔、堆排序)...
  2. 4.QT4中的connect的实现
  3. python编程培训多少钱-线下python培训要多少钱?
  4. 计算并输出1000以内的所有“完数”之和
  5. .NET 基础一步步一幕幕[out、ref、params]
  6. 【Spring-Cached】Cached之Caffeine
  7. 基于大数据的智慧旅游数据分析系统
  8. 操作系统实验报告 lab6
  9. 分布式微服框架Dubbo视频教程分享,已更新。
  10. PowerBuilder9.0连接ORACLE数据库
  11. 贝叶斯网络(概率图模型)
  12. 中国象棋人工智能实现
  13. django慢学日常
  14. 搜狗拼音输入法自定义格式的时间和日期并快捷键触发
  15. VS2019企业版密钥
  16. u盘格式化时提示“系统找不到指定文件”问题解决方法
  17. linux蓝牙适配器驱动安装失败,deepin官方论坛-深度科技官网旗下网站
  18. python识别魔方色块_解魔方的机器人攻略23 – 识别颜色(上)
  19. Shell正则表达式详解(一)
  20. PHP接口的概念与接口的应用场景

热门文章

  1. 基于php的家装主题装修网站-计算机毕业设计
  2. 银河麒麟V10-SP2服务器操作系统安装vnc
  3. 电力设备内部绝缘油泄漏检测图像数据集(300多张数据,VOC标签)
  4. 基于Astar算法的栅格地图最优路径搜索matlab仿真,可以修改任意数量栅格
  5. 链接脚本之bss段的清空
  6. 【JumpServer-初识篇】一键搭建JumpServer堡垒机、对接server服务器主机
  7. 程序实训 | BigInt | 第一位数字
  8. LocalDate使用手册~
  9. 分享巧记Linux命令的方法
  10. win7 系统密码清除