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. MySQL数据库----数据操作

    注意的几点:1.如果你在cmd中书命令的时候,输入错了就用\c跳出 2.\s查看配置信息 一.操作文件夹(库) 增:create database db1 charset utf8; 删:drop d ...

  2. JavaScript实现表单验证

    表单验证可以通过 JavaScript 来完成 以下示例代码用于判断表单字段(Name)值是否存在,如果存在,则弹出信息,否则阻止表单提交: <!DOCTYPE html> <htm ...

  3. 20145331魏澍琛《网络对抗》Exp5 MSF基础应用

    20145331魏澍琛<网络对抗>Exp5 MSF基础应用 基础问题回答 1.用自己的话解释什么是exploit,payload,encode? exploit:渗透攻击的模块合集,将真正 ...

  4. 论文笔记——DenseNet

    <Densely Connected Convolutional Networks>阅读笔记 代码地址:https://github.com/liuzhuang13/DenseNet 首先 ...

  5. C# “试图访问已释放的资源”

    WinCE项目 VS2008 项目现有一个公共静态类PublicItems,一个窗体模板FormModel,三个继承自模板的子窗体. 现在想要实现在其中一个子窗体中对所有子窗体上一个Label显示进行 ...

  6. C语言中生产随机数 rand()函数

    参考资料:C语言中产生随机数 一:如果你只要产生随机数而不需要设定范围的话,你只要用rand()就可以了:rand()会返回一随机数值, 范围在0至RAND_MAX 间.RAND_MAX定义在stdl ...

  7. MVC ---- EF三层代码

    1.DAL层 using Night.Models; using System; using System.Collections.Generic; using System.Data.Entity. ...

  8. 基于R进行相关性分析--转载

    https://www.cnblogs.com/fanling999/p/5857122.html 一.相关性矩阵计算: [1] 加载数据: >data = read.csv("231 ...

  9. R语言 sub与gsub函数的区别

    > text <- c("we are the world", "we are the children") > sub("w&qu ...

  10. String中hashCode方法的线程安全

    class String{ //默认值是0 int hash; public int hashCode() { //将成员变量hash缓存到局部变量 int h = hash; //这里使用的是局部变 ...