HDU 4856 Tunnels

Tunnels

Time Limit: 1500ms

Memory Limit: 32768KB

This problem will be judged on HDU. Original ID: 4856
64-bit integer IO format: %I64d      Java class name: Main

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

Source

2014西安全国邀请赛

解题:状压dp。1<<(j-1)表示第i条隧道被选。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <climits>
 7 #include <vector>
 8 #include <queue>
 9 #include <cstdlib>
10 #include <string>
11 #include <set>
12 #include <stack>
13 #define LL long long
14 #define pii pair<int,int>
15 #define INF 0x3f3f3f3f
16 using namespace std;
17 const int maxn = 20;
18 struct Tunnels {
19     int u,v,x,y;
20 };
21 Tunnels e[maxn];
22 int n,m,g[maxn][maxn],dp[1<<15][maxn];
23 char mp[maxn][maxn];
24 int bfs(Tunnels &a,const Tunnels &b) {
25     queue< pii >q;
26     static int vis[maxn][maxn];
27     static const int dir[4][2] = {0,-1,-1,0,1,0,0,1};
28     memset(vis,-1,sizeof(vis));
29     q.push(make_pair(a.x,a.y));
30     vis[a.x][a.y] = 0;
31     while(!q.empty()) {
32         pii now = q.front();
33         q.pop();
34         if(now.first == b.u && now.second == b.v)
35             return vis[now.first][now.second];
36         for(int i = 0; i < 4; i++) {
37             int x = now.first+dir[i][0];
38             int y = now.second+dir[i][1];
39             if(vis[x][y] > -1 || mp[x][y] == ‘#‘) continue;
40             vis[x][y] = vis[now.first][now.second]+1;
41             q.push(make_pair(x,y));
42         }
43     }
44     return -1;
45 }
46 int main() {
47     while(~scanf("%d %d",&n,&m)) {
48         memset(mp,‘#‘,sizeof(mp));
49         for(int i = 1; i <= n; i++)
50             scanf("%s",mp[i]+1);
51         for(int i = 1; i <= m; i++)
52             scanf("%d %d %d %d",&e[i].u,&e[i].v,&e[i].x,&e[i].y);
53         for(int i = 1; i <= m; i++) {
54             for(int j = 1; j <= m; j++)
55                 g[i][j] = bfs(e[i],e[j]);
56         }
57         memset(dp,INF,sizeof(dp));
58         for(int i = 1; i <= m; i++) dp[1<<(i-1)][i] = 0;
59         int ans = INF;
60         for(int i = 1,M = 1 << m; i < M; i++) {
61             for(int j = 1; j <= m; j++) {
62                 if(i&(1<<(j-1))) {
63                     for(int k = 1; k <= m; k++) {
64                         if(k == j || (i&(1<<(k-1)) == 0) || g[k][j] == -1) continue;
65                         dp[i][j] = min(dp[i][j],dp[i^(1<<(j-1))][k]+g[k][j]);
66                     }
67                 }
68                 if(i == M-1) ans = min(ans,dp[i][j]);
69             }
70         }
71         printf("%d\n",ans == INF?-1:ans);
72     }
73     return 0;
74 }

时间: 2024-10-07 05:07:20

HDU 4856 Tunnels的相关文章

hdu 4856 Tunnels(bfs+状态压缩)

题目链接:hdu 4856 Tunnels 题目大意:给定一张图,图上有M个管道,管道给定入口和出口,单向,现在有人想要体验下这M个管道,问最短需要移动的距离,起点未定. 解题思路:首先用bfs处理出两两管道之间移动的距离,然后后用状态压缩求出最短代价,dp[i][j],i表示的已经走过的管道,j是当前所在的管道. #include <cstdio> #include <cstring> #include <queue> #include <algorithm&g

HDU 4856 Tunnels (最短路+状压DP)

题意:给你N*N的网格,'.'表示可以走,'#'表示不能走,m条管道,每条管道有起点和终点坐标, Bob每次可以走到相邻的网格花费1s,问Bob走完m条管道要花多少时间:Bob在管道内不计算时间 即计算Bob从管道 i 的出口走到管道 j 的入口的时间Dis(e[i],s[j])的最小和,起点可以任意: 思路:看了题解说是状态压缩DP然后深入理解了下. 首先算出d[e[i]][s[j]]的最短距离,不能到达为-1: dp[i][j] : 表示以 j 为起点状态为 i 的最小值.其中 i 是用十进

HDU 4856 Tunnels(BFS+状压DP)

HDU 4856 Tunnels 题目链接 题意:给定一些管道,然后管道之间走是不用时间的,陆地上有障碍,陆地上走一步花费时间1,求遍历所有管道需要的最短时间,每个管道只能走一次 思路:先BFS预处理出两两管道的距离,然后状态压缩DP求解,dp[s][i]表示状态s,停在管道i时候的最小花费 代码: #include <cstdio> #include <cstring> #include <queue> #include <algorithm> using

hdu 4856 Tunnels BFS+不回起点的TSP

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4856 注意到隧道是单向的 bfs求出距离以后套用TSP模板即可 注意日本人那本白书上的模板是最后要回到起点的 而本题并不回起点 具体的做法是建一个超级起点,跟图中每一个点都建花费为0的边,然后以之为起点跑一边即可 #include <cstring> #include <cstdlib> #include <cstring> #include <cmath> #

HDU 4856 Tunnels(bfs+状压dp)

题目大意:给你一个N*N的图让你到达所有的"."点,"#"不能通过,有m组每组有一个入口,一个出口,入口可以传送到出口,不知道经过m组的先后顺序,让你求出走过所有的"."的最小时间. 思路:先bfs出来所有的m之间的最短距离,然后dp[j][i] 表示,在j状态下开始第i步的最小路程,枚举找到一个最小的dp[1<<m - 1][i],就是最短距离,否则输出"-1". Tunnels Time Limit: 3000

HDU 4856

http://acm.hdu.edu.cn/showproblem.php?pid=4856 西安邀请赛的一道题,这道题我们当时在现场最后1h才发现时状态压缩dp,惊险写出 现在回头想发现当时有点呆,这种明显tsp模型的题目当时鬼迷心窍去写搜索,超时而不知悔改,实际是水题一道 #include <iostream> #include <map> #include <cstdio> #include <cstring> #include <queue&g

HDU 4856 (状态压缩DP+TSP)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4856 题目大意:有一个迷宫.迷宫里有些隧道,每个隧道有起点和终点,在隧道里不耗时.出隧道就耗时,你的任务是访问完所有隧道且仅一次,求最短耗时. 解题思路: 暑假练习的时候.把英文读了N遍也没理解题意. 其实就是个最后不回到开头的TSP. 首先求BFS求两两隧道之间的最短路,注意BFS的起点是隧道i的终点,BFS的终点是隧道j的起点. 一定要特判一下两个隧道终点和起点是否一样,如果一样话dis=0,

(tsp问题) hdu 4856

Tunnels Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1460    Accepted Submission(s): 435 Problem Description Bob is travelling in Xi’an. He finds many secret tunnels beneath the city. In his

hdu 4856 水dp

别看像搜索    试试就超时 ==,    想想还是用dp做吧: 因为只能从三个方向走   ,对于第一列只能从上往下走  所以很快就能求出第一列的dp[i][j] 到达表示这个位置的最大金币,对以后的每一列  先从左边过来更新一次,,,再有两种走法,往下走和往上走,用两个数组分别记下最大值   然后从这两个中找出最大值: #include<stdio.h> #include<string.h> #include<iostream> using namespace std