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

關於圖中邊權非零即一的寬度優先搜索c++

Description

譯自 BalticOI 2011 Day1 T3「Switch the Lamp On」
有一種正方形的電路元件,在它的兩組相對頂點中,有一組會用導線鏈接起來,另外一組則不會。
有 N×MN\times MN×M 個這樣的元件,你想將其排列成 NNN 行 MMM 列放在電路板上。電路板的左上角鏈接電源,右下角鏈接燈泡。

試求:至少要旋轉多少個正方形元件才能讓電源與燈泡連通,若無解則輸出 NO SOLUTION。spa


 

題目分析

記得以前誰的講課裏提到過這種「ex-BFS」?3d

只須要在隊列拓展的時候稍做更改:邊權爲一時在隊尾插入;邊權爲零在隊頭插入。正確性能夠由反證法獲得。code

 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 }

 

 

ENDblog

相關文章
相關標籤/搜索