• 【搜索 ex-BFS】bzoj2346: [Baltic 2011]Lamp


    关于图中边权非零即一的宽度优先搜索

    Description

    译自 BalticOI 2011 Day1 T3「Switch the Lamp On」
    有一种正方形的电路元件,在它的两组相对顶点中,有一组会用导线连接起来,另一组则不会。
    有 N×MN imes MN×M 个这样的元件,你想将其排列成 NNN 行 MMM 列放在电路板上。电路板的左上角连接电源,右下角连接灯泡。

    试求:至少要旋转多少个正方形元件才能让电源与灯泡连通,若无解则输出 NO SOLUTION。


    题目分析

    记得之前谁的讲课里提到过这种“ex-BFS”?

    只需要在队列拓展的时候稍作更改:边权为一时在队尾插入;边权为零在队头插入。正确性可以由反证法得到。

     1 #include<bits/stdc++.h>
     2 
     3 struct point
     4 {
     5     int x,y;
     6     point(int a=0, int b=0):x(a), y(b) {}
     7 };
     8 int n,m,dis[533][533];
     9 char str[533][533];
    10 std::deque<point> q;
    11 
    12 bool legal(int x, int y)
    13 {
    14     return x>=0&&y>=0&&x<=n&&y<=m;
    15 }
    16 bool check(int x, int y)
    17 {
    18     return str[x][y]=='\';
    19 }
    20 void update(int x, int y, int v)
    21 {
    22     if (dis[x][y] > v){
    23         dis[x][y] = v;
    24         if (q.empty()||v > dis[q.front().x][q.front().y])
    25             q.push_back(point(x, y));
    26         else q.push_front(point(x, y));
    27     }
    28 }
    29 int main()
    30 {
    31     memset(dis, 0x3f3f3f3f, sizeof dis);
    32     scanf("%d%d",&n,&m);
    33     if ((n+m)%2){
    34         puts("NO SOLUTION");
    35         return 0;
    36     }
    37     for (int i=1; i<=n; i++) scanf("%s",str[i]+1);
    38     dis[0][0] = 0, q.push_front(point(0, 0));
    39     while (q.size())
    40     {
    41         point tt = q.front();
    42         q.pop_front();
    43         if (legal(tt.x+1, tt.y+1)){
    44             if (check(tt.x+1, tt.y+1))
    45                 update(tt.x+1, tt.y+1, dis[tt.x][tt.y]);
    46             else update(tt.x+1, tt.y+1, dis[tt.x][tt.y]+1);
    47         }
    48         if (legal(tt.x+1, tt.y-1)){
    49             if (check(tt.x+1, tt.y))
    50                 update(tt.x+1, tt.y-1, dis[tt.x][tt.y]+1);
    51             else update(tt.x+1, tt.y-1, dis[tt.x][tt.y]);
    52         }
    53         if (legal(tt.x-1, tt.y+1)){
    54             if (check(tt.x, tt.y+1))
    55                 update(tt.x-1, tt.y+1, dis[tt.x][tt.y]+1);
    56             else update(tt.x-1, tt.y+1, dis[tt.x][tt.y]);
    57         }
    58         if (legal(tt.x-1, tt.y-1)){
    59             if (check(tt.x, tt.y))
    60                 update(tt.x-1, tt.y-1, dis[tt.x][tt.y]);
    61             else update(tt.x-1, tt.y-1, dis[tt.x][tt.y]+1);
    62         }
    63     }
    64     printf("%d
    ",dis[n][m]);
    65     return 0;
    66 }

    END

  • 相关阅读:
    PAT2019顶级7-2:美丽的序列(线段树+DP)
    ZOJ2112 Dynamic Rank(可持久化线段树套树状数组)
    CF1353E K-periodic Garland(动态规划)
    CF1353D Constructing the array(优先队列)
    HDU2069 Coin Change(基础DP)
    surf(树状数组+DP)
    双倍快乐(回文树)
    ZOJ3591 Nim(博弈论)
    HDU6601 Keep On EveryThing But Triangle(可持久化线段树)
    HDU6599 I Love Palindrome String(回文树)
  • 原文地址:https://www.cnblogs.com/antiquality/p/9475897.html
Copyright © 2020-2023  润新知