Tunnels

Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 844    Accepted Submission(s): 249

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

记忆化搜索

view code#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
int dp[15][1<<15];
bool vis[15][1<<16];
int bit[25], n, m;
char str[20][20];
int dis[25][25], ans, tot;
int dx[4] = {0, 0, -1, 1};
int dy[4] = {-1, 1, 0, 0}; struct node
{
int x, y, dis;
node() {}
node(int x, int y, int dis):x(x),y(y),dis(dis) {}
bool operator == (const node &o){
return x==o.x && y==o.y;
}
}; struct edge
{
node a, b;
}sto[20]; void init()
{
for(int i=0; i<20; i++) bit[i] = 1<<i;
} bool is_ok(int x, int y)
{
if(x<0 || x>=n || y<0 || y>=n || str[x][y]=='#') return 0;
return true;
} bool look[20][20];
int getdis(node a, node b)
{
queue<node >q;
q.push(node(a.x, a.y, 0));
memset(look, 0, sizeof(look));
look[a.x][a.y]=1;
while(!q.empty())
{
node o = q.front(); q.pop();
if(o==b) return o.dis;
for(int i=0; i<4; i++)
{
int x = o.x+dx[i], y = o.y+dy[i];
if(!is_ok(x, y) || look[x][y]) continue;
q.push(node(x, y, o.dis+1));
look[x][y] = 1;
}
}
return INF;
} int dfs(int u, int s)
{
if(vis[u][s]) return dp[u][s];
if(s==tot) return 0;
vis[u][s] = 1;
int &res = dp[u][s];
res = INF;
for(int i=0; i<n; i++)
{
if(bit[i]&s || u==i) continue;
res = min(dfs(i, s|bit[i])+dis[u][i], res);
}
return res;
} void solve()
{
for(int i=0; i<n; i++) scanf("%s", str[i]);
for(int i=0; i<m; i++)
{
scanf("%d%d%d%d", &sto[i].a.x, &sto[i].a.y, &sto[i].b.x, &sto[i].b.y);
sto[i].a.x --; sto[i].a.y--; sto[i].b.x--; sto[i].b.y--;
for(int j=0; j<i; j++)
{
dis[i][j] = getdis(sto[i].b, sto[j].a);
dis[j][i] = getdis(sto[j].b, sto[i].a);
}
}
memset(vis, 0, sizeof(vis));
int ans = INF;
tot = bit[m]-1;
for(int i=0; i<m; i++){
int tmp = dfs(i, bit[i]);
ans = min(tmp, ans);
}
if(ans==INF) ans = -1;
printf("%d\n", ans);
} int main()
{
// freopen("in.txt", "r", stdin);
init();
while(scanf("%d%d", &n, &m)>0) solve();
return 0;
}

hdu 4856 Tunnels (记忆化搜索)的更多相关文章

  1. 不要62 hdu 2089 dfs记忆化搜索

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=2089 题意: 给你两个数作为一个闭区间的端点,求出该区间中不包含数字4和62的数的个数 思路: 数位dp中 ...

  2. hdu 1078(dfs记忆化搜索)

    题意:容易理解... 思路:我开始是用dfs剪枝做的,968ms险过的,后来在网上学习了记忆化搜索=深搜形式+dp思想,时间复杂度大大降低,我个人理解,就是从某一个点出发,前面的点是由后面的点求出的, ...

  3. hdu 4826(dp + 记忆化搜索)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4826 思路:dp[x][y][d]表示从方向到达点(x,y)所能得到的最大值,然后就是记忆化了. #i ...

  4. POJ 1198 / HDU 1401 Solitaire (记忆化搜索+meet in middle)

    题目大意:给你一个8*8的棋盘,上面有四个棋子,给你一个初始排布,一个目标排布,每次移动,可以把一个棋子移动到一个相邻的空位,或者跨过1个相邻的棋子,在保证棋子移动不超过8次的情况下,问能否把棋盘上的 ...

  5. hdu 4345 Permutation 记忆化搜索

    思路:实际上求的是和小于等于n的质数的种类数!!! 代码如下: #include<iostream> #include<stdio.h> #include<algorit ...

  6. POJ1088 滑雪题解+HDU 1078(记忆化搜索DP)

    Description Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道 ...

  7. hdu1078 记忆化搜索

    /* hdu 1078 QAQ记忆化搜索 其实还是搜索..因为里面开了一个数组这样可以省时间 (dp[x][y]大于0就不用算了直接返回值) */ #include<stdio.h> #i ...

  8. HDU 1429 (BFS+记忆化状压搜索)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1429 题目大意:最短时间内出迷宫,可以走回头路,迷宫内有不同的门,对应不同的钥匙. 解题思路: 要是 ...

  9. HDU 1176 免费馅饼(记忆化搜索)

    免费馅饼 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

随机推荐

  1. KMP算法详解 --- 彻头彻尾理解KMP算法

    前言 之前对kmp算法虽然了解它的原理,即求出P0···Pi的最大相同前后缀长度k. 但是问题在于如何求出这个最大前后缀长度呢? 我觉得网上很多帖子都说的不是很清楚,总感觉没有把那层纸戳破, 后来翻看 ...

  2. 重构第17天提取父类(Extract SuperClass)

    今天的重构来自 Martin Fowler的http://refactoring.com/catalog/extractSuperclass.html. 理解:本文中的“提取父类”是指类中有一些字段或 ...

  3. Jcrop简单实用

    今天有一个项目的功能需求 “在上传照片的时候能进行裁剪”,网上找了下,发现有Jcrop这款插件,自己试了下,感觉很不错,蛮好用的.又能增加用户体验,测试了兼容性也很好,所以在这里分享下 首先,可以到官 ...

  4. bootstrap学习笔记(6)

    滚动监听        滚动监听有两种方式:        (1)通过属性控制        向想要滚动监听的元素添加如下属性data-spy="scroll",然后添加data- ...

  5. [译] 你应该升级 MQTT3.1.1 的6个理由

    原文 6 facts why it’s worth upgrading to the brand new MQTT 3.1.1version 摘要:新版 MQTT 3.1.1 终于在 2014 年 1 ...

  6. Android 手机卫士13--进程设置

    1.显示隐藏系统进程 修改ProcessManagerActivity的Adapter ..... @Override public int getCount() { if(SpUtil.getBoo ...

  7. 关于使用ResultSet ---结果集没有当前行

    Resultset返回的结果集是从结果的前一句开始的,也就是说一开始的resultset是没有的,所以,一般使用的时候,需要这样子写:      while( resultSet.next() ){ ...

  8. c++中string的常用函数说明

    string可以说是是字符数组的升级版,使用更加啊方便,不容易出错.本文对string的常用函数进行简单介绍,做到会用即可. string中的常用函数分为四类,即赋值,添加,比较和删除. 一.赋值 1 ...

  9. 存放事务码及其描述的TABLE是TSTC、TSTCT。

    存放事务码及其描述的TABLE是TSTC.TSTCT.

  10. Linux平台Makefile文件的编写基础入门(课堂作业)

    根据老师的要求,写一个超简单的makefile准备:       准备三个文件:file1.c, file2.c, file2.h       file1.c: #include "file ...