码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 4856 Tunnels (bfs + 状压dp)

时间:2014-10-17 21:48:31      阅读:182      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   io   os   ar   for   sp   

题目链接

题意:

一个边长为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 个密道能才发生转移。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <queue>
 5 #include <cstring>
 6 #include <cstdlib>
 7 #include <algorithm>
 8 #define LL __int64
 9 const int maxn = 20+10;
10 using namespace std;
11 const int INF = 1<<28;
12 char s[maxn][maxn];
13 int c[maxn][maxn], d[1<<17][20], n;
14 int dx[] = {0, 0, 1, -1};
15 int dy[] = {1, -1, 0, 0};
16 struct node
17 {
18     int x, y, step;
19 }pos, ne;
20 int bfs(int a, int b, int c, int d)
21 {
22     queue<node>q;
23     int vis[maxn][maxn], i;
24     memset(vis, 0, sizeof(vis));
25     ne.x = a; ne.y = b; ne.step = 0;
26     vis[a][b] = 1;
27     q.push(ne);
28     while(!q.empty())
29     {
30         pos = q.front();
31         q.pop();
32         if(pos.x == c && pos.y == d)
33         return pos.step;
34         for(i = 0; i < 4; i++)
35         {
36             ne.x = pos.x+dx[i];
37             ne.y = pos.y+dy[i];
38             ne.step = pos.step+1;
39             if(!(ne.x>=1&&ne.x<=n && ne.y>=1&&ne.y<=n)) continue;
40             if(s[ne.x][ne.y]==#) continue;
41             if(vis[ne.x][ne.y]) continue;
42             q.push(ne);
43             vis[ne.x][ne.y] = 1;
44         }
45     }
46     return INF;
47 }
48 int main()
49 {
50     int m, i, j, k, ans;
51     int x1[maxn], y1[maxn], x2[maxn], y2[maxn];
52     while(~scanf("%d%d", &n, &m))
53     {
54         memset(c, 0, sizeof(c));
55         memset(s, 0, sizeof(s));
56         for(i = 1; i <= n; i++)
57         {
58             getchar();
59             for(j = 1; j <= n; j++)
60             scanf("%c", &s[i][j]);
61         }
62         for(i = 0; i < m; i++)
63          cin>>x1[i]>>y1[i]>>x2[i]>>y2[i];
64         for(i = 0; i < m; i++)
65         for(j = 0; j < m; j++)
66         {
67             if(i == j) continue;
68             c[i][j] = bfs(x2[i], y2[i], x1[j], y1[j]);
69         }
70         for(i = 0; i < (1<<m); i++)
71         for(j = 0; j < m; j++)
72         d[i][j] = INF;
73 
74         for(i = 0; i < m; i++)
75         d[1<<i][i] = 0;
76 
77         for(i = 0; i < (1<<m); i++)
78         for(j = 0; j < m; j++)
79         if(d[i][j]!=INF)
80         for(k = 0; k < m; k++)
81         {
82             if(!(i&(1<<k)) && c[j][k]!=INF)
83             d[i|(1<<k)][k] = min(d[i|(1<<k)][k], d[i][j]+c[j][k]);
84         }
85         ans = INF;
86         for(i = 0; i < m; i++)
87         ans = min(ans, d[(1<<m)-1][i]);
88         if(ans == INF) printf("-1\n");
89         else
90         printf("%d\n", ans);
91     }
92     return 0;
93 }

 

hdu 4856 Tunnels (bfs + 状压dp)

标签:style   blog   http   color   io   os   ar   for   sp   

原文地址:http://www.cnblogs.com/bfshm/p/4032042.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!