双端队列BFS

175. 电路维修

电路板的整体结构是一个 R 行 C 列的网格(R,C500),如下图所示。

电路.png

她准备通过计算,旋转最少数量的元件,使电源与发动装置通过若干条短缆相连。

注意:只能走斜向的线段,水平和竖直线段不能走。

输入格式

输入文件包含多组测试数据。

第一行包含一个整数 T,表示测试数据的数目。

对于每组测试数据,第一行包含正整数 R 和 C,表示电路板的行数和列数。

之后 R 行,每行 C 个字符,字符是"/""\"中的一个,表示标准件的方向。

输出格式

对于每组测试数据,在单独的一行输出一个正整数,表示所需的最小旋转次数。

如果无论怎样都不能使得电源和发动机之间连通,输出 NO SOLUTION

数据范围

≤ ≤ 500
≤ ≤ 5

输入样例:

1
3 5
\\/\\
\\///
/\\\\

输出样例:

1

思路:

  这是个有权值的搜索路径问题,该路线权值由该点是否需要改变决定。

  这里使用双端队列deque,将权值为0的放队首,权值为1的放队尾。

  --日后再更

代码:

#include <bits/stdc++.h>
#define x first
#define y second

using namespace std;

typedef pair<int ,int> PII;

const int N = 505, M = 505 * 505;


int T, n, m;
char g[N][N];
int dist[N][N];
bool book[N][N];
int NEXT[4][2] = {{-1,1},{1,1},{1,-1},{-1,-1}};
int aa[4][2] = {{-1,0},{0,0},{0,-1},{-1,-1}};

int bfs(){
    deque<PII> q;
    memset(book,0,sizeof book);
    memset(dist,0x3f,sizeof dist);

    q.push_back({0, 0});
    dist[0][0] = 0;
    //cout << q.size() << endl;
    while(q.size()){
        PII t = q.front();
        q.pop_front();
        int x = t.x, y = t.y;
        if(x == n && y == m){
            return dist[x][y];
        }
        if(book[x][y])continue;
        book[x][y] = true;
        char s[10] = "/\\/\\";
        for(int i = 0; i < 4; i++){
            int a = x + NEXT[i][0];
            int b = y + NEXT[i][1];
            if(a < 0 || b < 0 || a > n || b > m)continue;
            if(book[a][b])continue;
            int ga = x + aa[i][0], gb = y + aa[i][1];
            int w = (g[ga][gb] != s[i]);
            int DIST = dist[x][y] + w;
            if(DIST < dist[a][b]) dist[a][b] = DIST;
            //dist[a][b] = dist[x][y] + w;
            //printf("w = %d  %d  %d  dist = %d  x = %d y = %d  ga = %d gb = %d\n",w,a,b,dist[a][b],x,y,ga,gb);
            if(w == 0)  q.push_front({a,b});
            else        q.push_back({a,b});
                    
            
        }
    }
    
    return -1;
}
int main(){
    cin >> T;
    while(T--){
        cin >> n >> m;
        for(int i = 0; i < n; i++)scanf("%s",g[i]);
        if((n + m) & 1) printf("NO SOLUTION\n");
        else            printf("%d\n",bfs());
        
        
    }
    
    
    return 0;
}

 






posted @ 2022-02-17 15:17  荣荣荣荣荣荣  阅读(121)  评论(0)    收藏  举报