zoukankan      html  css  js  c++  java
  • hdu 4856 Tunnels (bfs + 状压dp)

    题目链接

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

     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
    ");
    89         else
    90         printf("%d
    ", ans);
    91     }
    92     return 0;
    93 }
  • 相关阅读:
    github not authorized eclipse 关于 代码不能提交到GitHub
    idea 导入项目后 有的项目目录结构不展开解决办法
    intellij idea 主题大全,看不惯idea 那2种主题的来这里了
    win10 系统输入法与 idea的 ctr+shift+f 快捷键冲突,解决办法
    此地址使用了一个通常用于网络浏览以外目的的端口。出于安全原因,Firefox 取消了该请求。
    关于IntelliJ IDEA有时候快捷键无效的说明
    杜恩德是谁?
    oracle如何连接别人的数据库,需要在本地添加一些配置
    2.6---找有环链表的开头结点(CC150)
    2.3---删除链表的结点,不提供头结点(CC150)
  • 原文地址:https://www.cnblogs.com/bfshm/p/4032042.html
Copyright © 2011-2022 走看看