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
 
题目大意:在一张nxn(n<16)的图中,"."表示空白区域,"#"表示障碍,每次移动的方向是上下左右之一,每移动一次耗时加1。有m条已知进口和出口的隧道,在隧道中移动不花时间。问要游览完所有的隧道最少需要的时间是多少?顺序自选。
题目分析:一看数据规模那么小,就想到是状压DP了。但要用BFS预处理出两两隧道之间的距离(起始隧道的出口与终止隧道的进口的距离)。定义状态dp(i,j)表示已经走过的隧道集合为i,并且当前在j位置时已经花掉的最小时间。则状态转移方程为dp(i|(1<<k),k)=min(dp(i|(1<<k),k),dp(i,j)+dist(j,k))。
 
 
代码如下:
# include<iostream>
# include<cstdio>
# include<queue>
# include<cstring>
# include<algorithm>
using namespace std;
const int INF=100000;
struct TT
{
int sx,sy,ex,ey;
};
struct node
{
int x,y,t;
node(int _x,int _y,int _t):x(_x),y(_y),t(_t){}
};
TT t[15];
char mp[20][20];
int dist[20][20];
int vis[20][20],n,m,dp[1<<15][15];
int d[4][2]={{0,-1},{0,1},{-1,0},{1,0}};
int bfs(int sx,int sy,int ex,int ey)
{
queue<node>q;
memset(vis,0,sizeof(vis));
vis[sx][sy]=1;
q.push(node(sx,sy,0));
while(!q.empty())
{
node u=q.front();
q.pop();
if(u.x==ex&&u.y==ey)
return u.t;
for(int i=0;i<4;++i){
int nx=u.x+d[i][0],ny=u.y+d[i][1];
if(nx>=1&&nx<=n&&ny>=1&&ny<=n&&!vis[nx][ny]&&mp[nx][ny]!='#'){
vis[nx][ny]=1;
q.push(node(nx,ny,u.t+1));
}
}
}
return INF;
}
void init()
{
for(int i=0;i<m;++i)
for(int j=0;j<m;++j)
dist[i][j]=bfs(t[i].ex,t[i].ey,t[j].sx,t[j].sy);
}
void DP()
{
int tot=1<<m;
for(int i=0;i<tot;++i)
for(int j=0;j<m;++j)
dp[i][j]=INF;
for(int i=0;i<m;++i)
dp[1<<i][i]=0;
for(int i=1;i<tot;++i){
for(int j=0;j<m;++j){
if(i&(1<<j))
continue;
int sta=i|(1<<j);
for(int k=0;k<m;++k){
if(i&(1<<k))
dp[sta][j]=min(dp[sta][j],dp[i][k]+dist[k][j]);
}
}
}
int ans=INF;
for(int i=0;i<m;++i)
ans=min(ans,dp[tot-1][i]);
if(ans==INF)
printf("-1\n");
else
printf("%d\n",ans);
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
for(int i=1;i<=n;++i)
scanf("%s",mp[i]+1);
for(int i=0;i<m;++i)
scanf("%d%d%d%d",&t[i].sx,&t[i].sy,&t[i].ex,&t[i].ey);
init();
DP();
}
return 0;
}

  

HDU-4856 Tunnels (BFS+状压DP)的更多相关文章

  1. hdu 4856 Tunnels (bfs + 状压dp)

    题目链接 The input contains mutiple testcases. Please process till EOF.For each testcase, the first line ...

  2. hdu 3247 AC自动+状压dp+bfs处理

    Resource Archiver Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 100000/100000 K (Java/Ot ...

  3. hdu 2825 aC自动机+状压dp

    Wireless Password Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

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

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

  5. hdu 4856 Tunnels(bfs+状态压缩)

    题目链接:hdu 4856 Tunnels 题目大意:给定一张图,图上有M个管道,管道给定入口和出口,单向,如今有人想要体验下这M个管道,问最短须要移动的距离,起点未定. 解题思路:首先用bfs处理出 ...

  6. HDU 5765 Bonds(状压DP)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5765 [题目大意] 给出一张图,求每条边在所有边割集中出现的次数. [题解] 利用状压DP,计算不 ...

  7. 孤岛营救问题(BFS+状压DP)

    孤岛营救问题 https://www.luogu.org/problemnew/show/P4011 用状压DP标记拿到钥匙的数量 #include<iostream> #include& ...

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

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

  9. HDU-3681-Prison Break(BFS+状压DP+二分)

    Problem Description Rompire is a robot kingdom and a lot of robots live there peacefully. But one da ...

随机推荐

  1. netty4----日志框架的检查

    https://segmentfault.com/a/1190000005797595 2016年06月25日  ·  4.1k 次阅读 Netty4.x Internal Logger机制 nett ...

  2. spoj1825 Free tour II

    题目链接 一道神奇的点分治 貌似有很多做法,我觉得BIT要好些一些(雾 要求经过黑点数<k就用BIT区间查询前缀 对于每个点用  BIT[0,k-经过黑点数]的最大值+路径长度 使用点分治做到O ...

  3. 【Python】【Flask】前端调用后端方法

    后端代码: @app.route("/test",methods=['POST','GET']) def test(): return "我是测试的" 前端代码 ...

  4. Linux下useradd命令创建的用户不能登录的问题

    Linux下useradd命令创建的用户不能登录的问题  问题: 用useradd命令新创建一个用户tester 密码pwdtest mkdir -p /home/tester(创建文件夹) user ...

  5. Python3基础 print \n换行

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  6. openwrt的编译系统是如何生成squashfs文件系统的

    答:请看include/image.mk中的以下定义: define Image/mkfs/squashfs $(STAGING_DIR_HOST)/bin/mksquashfs4 $(call mk ...

  7. BZOJ5189: [Usaco2018 Jan]Cow at Large 贪心+LCA

    BZOJ没有题面QAQ,题目链接 洛谷有:题目链接 这题首先要读懂题..(洛谷的翻译有点迷 就是指定根节点,然后可以在叶子结点放个人,然后奶牛在根,问最少要在叶子结点放多少人才能让奶牛走不到叶子结点( ...

  8. [BZOJ1103][POI2007]大都市meg dfs序+树状数组

    Description 在经济全球化浪潮的影响下,习惯于漫步在清晨的乡间小路的邮递员Blue Mary也开始骑着摩托车传递邮件了.不过,她经常回忆起以前在乡间漫步的情景.昔日,乡下有依次编号为1..n ...

  9. 编译安装lamp (php)

    用户账号及权限管理 用户账号:'user'@'host' user: 用户名 host: 此用户访问mysqld服务时允许通过哪些主机远程创建连接: host类型:IP.网络地址.主机名.通配符(%和 ...

  10. BZOJ 4416 【SHOI2013】 阶乘字符串

    题目链接:阶乘字符串 又是一道不会做的题……看了题解后我被吓傻了…… 首先我们可以有一个显然的\(O(2^nn)\)的做法.我们先预处理出\(g_{i,j}\)表示字符串中\(i\)号位置开始第一个\ ...