AcWing 175. Service circuits (deque BFS)

Topic links: Click here
Here Insert Picture Description
Here Insert Picture Description
Here Insert Picture Description

We can each grid point (point of intersection of horizontal and vertical lines) on the circuit board is regarded as the undirected graph nodes. If two nodes x x and Y Y is one of two small squares on the corners, then x x and Y Y is connected between the edges. If the standard (diagonal) of the box with x x to Y Y segment overlaps the right edge of 0 0 ; if perpendicular, to the right side 1 1 (rotation of the need 1 1 times to connect). Then, we find the shortest distance left to bottom right of the figure in this free, you get the answer.

This is an edge weight is either 0 or 1 is not directed graph. On this map, we can deque wide search is calculated. Overall framework broad general algorithm similar search, only slightly changed direction in the branch extension on each node. If this branch is the edge weights 0 side, put the new node along the branches reach into the team from the team head ; if this branch is the edge weights of 1 side, as a general wide search as from the end of the team team . As a result, we can still guarantee from the value of the node corresponding queues at any time have a broad search, "two" and "monotonic", each node is first accessed, you can get left on angular shortest distance to the node.

Because each node need only visit once, so the time complexity of the algorithm is THE ( R C ) O(R*C)

This property also has a problem, in fact, half of the mesh grid'll never get in (as shown in red dots), so you can judge it special.

Details of the deal: the number of each grid of numbers and each grid point is not the same, pay attention to the wording of two pairs of increment array.

#include<iostream>
#include<cstdio>
#include<cstring>
#include<deque>
#include<algorithm>

using namespace std;
typedef pair<int,int> PII;
const int N = 510;

int dx[] = {-1, -1, 1, 1};      // 当前格点四周的新格点
int dy[] = {-1, 1, 1, -1};

int ix[] = {-1, -1, 0, 0};      // 当前格点四周的格子
int iy[] = {-1, 0, 0, -1};

char cs[5] = "\\/\\/";

int n, m;
char g[N][N];
int d[N][N];
bool st[N][N];                  // 存储每个点的最短路是否已经确定

int bfs()
{
    deque<PII> q;
    memset(d, 0x3f, sizeof d);
    memset(st, false, sizeof st);
    
    q.push_back({0, 0});
    d[0][0] = 0;
    
    while(q.size())
    {
        auto t = q.front();
        q.pop_front();
        
        int x = t.first, y = t.second;       // (x,y)简化后续代码
        
        if(x == n && y == m)    return d[x][y];
        
        if(st[x][y])    continue;
        
        st[x][y] = true;
        
        for(int i = 0; i < 4; ++i)
        {
            int a = x + dx[i], b = y + dy[i];       // (x,y)扩展出的新格点(a,b)
            
            if(a < 0 || a > n || b < 0 || b > m)    continue;
            
            int ga = x + ix[i], gb = y + iy[i];     // (x,y)扩展出的格子(ga,gb)
            
            int dist = d[x][y] + (g[ga][gb] != cs[i]);

            if(dist < d[a][b])
            {
                d[a][b] = dist;

                if(g[ga][gb] != cs[i])  q.push_back({a, b});
                else    q.push_front({a, b});
            }
        }
    }
    
    return -1;      // 不会被执行到
}

int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d%d", &n, &m);      // n行m列的格子
        for(int i = 0; i < n; ++i)  scanf("%s", g[i]);
        
        if((n + m) & 1)   puts("NO SOLUTION");
        else    printf("%d\n", bfs());
    }
    
    return 0;
}
Published 844 original articles · won praise 135 · Views 150,000 +

Guess you like

Origin blog.csdn.net/qq_42815188/article/details/105082537