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

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

Description

译自 BalticOI 2011 Day1 T3「Switch the Lamp On」
有一种正方形的电路元件,在它的两组相对顶点中,有一组会用导线连接起来,另一组则不会。
有 N×MN\times 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\n",dis[n][m]);
65     return 0;
66 }

 

 

END

posted @ 2018-08-14 17:16  AntiQuality  阅读(307)  评论(0编辑  收藏  举报