题目链接

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.

题意:

一个边长为n的正方形网格图,其中有一些点' . '表示可达,' # '表示不可达,你不能走到不可达的点上,以及每一个单位时间你只能走到相邻的网格(上下左右)。现在给你m条密道,每条密道起始位置(x1,y1),终点位置(x2,y2),当你从起点进去后能瞬间从终点位置出来(不花时间),但是每条密道你只能走一遍。现在,你可以选择任意一个可达的点作为起点,问能否在满足条件下走完所有的密道,有解输出最短时间,否则输出-1。

分析:

先用bfs处理出来每个隧道之间的距离,然后就是走的各个隧道之间的顺序,可以用状压dp来做,

dp[ i ][ j ]表示已经经过的密道状态为 i (i为压缩状态,二进制的每一位表示相应的密道是否已经走过,走过为1,否则为0),最后一个经过的密道是j时的最小用时。

状态转移方程为:dp[ i | ( 1 << k ) ][ k ]  = min { dp[ i | ( 1 << k ) ][ k ] , dp[ i ][ j ] + dist[ j ][ k ] } 。
其中必须保证dp[ i ][ j ]已经有了的状态,dist[ j ][ k ]不是INF ( j 出发能到达 k ),以及状态 i 中不包含第 k 个密道能才发生转移。

 #include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define LL __int64
const int maxn = +;
using namespace std;
const int INF = <<;
char s[maxn][maxn];
int c[maxn][maxn], d[<<][], n;
int dx[] = {, , , -};
int dy[] = {, -, , };
struct node
{
int x, y, step;
}pos, ne;
int bfs(int a, int b, int c, int d)
{
queue<node>q;
int vis[maxn][maxn], i;
memset(vis, , sizeof(vis));
ne.x = a; ne.y = b; ne.step = ;
vis[a][b] = ;
q.push(ne);
while(!q.empty())
{
pos = q.front();
q.pop();
if(pos.x == c && pos.y == d)
return pos.step;
for(i = ; i < ; i++)
{
ne.x = pos.x+dx[i];
ne.y = pos.y+dy[i];
ne.step = pos.step+;
if(!(ne.x>=&&ne.x<=n && ne.y>=&&ne.y<=n)) continue;
if(s[ne.x][ne.y]=='#') continue;
if(vis[ne.x][ne.y]) continue;
q.push(ne);
vis[ne.x][ne.y] = ;
}
}
return INF;
}
int main()
{
int m, i, j, k, ans;
int x1[maxn], y1[maxn], x2[maxn], y2[maxn];
while(~scanf("%d%d", &n, &m))
{
memset(c, , sizeof(c));
memset(s, , sizeof(s));
for(i = ; i <= n; i++)
{
getchar();
for(j = ; j <= n; j++)
scanf("%c", &s[i][j]);
}
for(i = ; i < m; i++)
cin>>x1[i]>>y1[i]>>x2[i]>>y2[i];
for(i = ; i < m; i++)
for(j = ; j < m; j++)
{
if(i == j) continue;
c[i][j] = bfs(x2[i], y2[i], x1[j], y1[j]);
}
for(i = ; i < (<<m); i++)
for(j = ; j < m; j++)
d[i][j] = INF; for(i = ; i < m; i++)
d[<<i][i] = ; for(i = ; i < (<<m); i++)
for(j = ; j < m; j++)
if(d[i][j]!=INF)
for(k = ; k < m; k++)
{
if(!(i&(<<k)) && c[j][k]!=INF)
d[i|(<<k)][k] = min(d[i|(<<k)][k], d[i][j]+c[j][k]);
}
ans = INF;
for(i = ; i < m; i++)
ans = min(ans, d[(<<m)-][i]);
if(ans == INF) printf("-1\n");
else
printf("%d\n", ans);
}
return ;
}

hdu 4856 Tunnels (bfs + 状压dp)的更多相关文章

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

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

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

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

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

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

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

    Problem Description Bob is travelling in Xi’an. He finds many secret tunnels beneath the city. In hi ...

  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. [百度空间] [原] 全局operator delete重载到DLL

    由于很久没有搞内存管理了,很多细节都忘记了今天项目要用到operator delete重载到DLL,发现了问题,网上搜索以后,再对比以前写的代码,发现了问题:原来MSVC默认的operator new ...

  2. jQuery提升性能技巧及个人总结

    1.将jquery对象缓存起来在for循环中,不要每次都要访问数组的length属性,我们应该先将对象缓存进一个变量然后再操作,如下所示: 代码如下:var myLength = myArray.le ...

  3. 【译】 沙箱中的间谍 - 可行的 JavaScript 高速缓存区攻击

    王龑 - MAY 27, 2015 原文连接 The Spy in the Sandbox – Practical Cache Attacks in Javascript 相关论文可在 https:/ ...

  4. IE6中常见兼容性问题及浏览器显示难题

    1.双倍边距Bug 问题描述:假如有一个ul,里面有若干li,当li设置为左浮动时,此时设置li的margin-left为10px,会在最左侧呈现双倍情况.即20px 正常显示: IE6显示: 修正方 ...

  5. HDU 3255 Farming (线段树+扫面线,求体积并)

    题意:在一块地上种蔬菜,每种蔬菜有个价值.对于同一块地蔬菜价值高的一定是最后存活,求最后的蔬菜总值. 思路:将蔬菜的价值看做高度的话,题目就转化成求体积并,这样就容易了. 与HDU 3642 Get ...

  6. ThreadPoolTaskExecutor异步的处理报警发送邮件短信比较耗时的东东

    package com.elong.ihotel.util; import org.springframework.beans.factory.DisposableBean; import org.s ...

  7. Struts2.0 去掉action后缀名

    刚刚接触Struts2.0,发现默认请求都会带着后缀名:action 就如下图,url地址中会暴露login.action(请原谅struts拼写错误..) 作为一个URL简洁爱(chu)好(nv)者 ...

  8. 4 tips for staying productive on Friday

    4 tips for staying productive on Friday如何让你的周五和周一一样有效率1.Schedule Your Day with Tasks 用任务计划一天 Sometim ...

  9. [iOS]SourceTree+oschina实现代码远程托管

    在iOS开发, 涉及到多人协同开发的时候, 这个时候, 我们就得利用版本控制系统(例如GIT), 来合并和管理代码了, 今天我们来讲一下, 利用 SourceTree+oschina进行版本控制 先来 ...

  10. 预编译头文件 StdAfx.h

    预编译头文件: 最常见的使用场景就是 StdAfx.h 文件,在这个文件中包含常用的头文件,比如windows.h,cstdio,string,别的 .cpp 文件去包含 StdAfx.h 头文件.编 ...