zoukankan      html  css  js  c++  java
  • SPOJ KATHTHI

    以前并不知道这个trick。

    $01BFS$,在$bfs$的时候用一个双端队列来维护,如果边权为$1$就添加到队尾,边权为$0$就添加到队首。

    还有一个小trick就是我们可以开一个$dis$数组来代替$vis$数组做类似于$dp$的操作,因为双端插入的特性使$vis$的表示可能产生歧义,每一次能更新$dis$即入队,这样子也刚好对应了最短路的意义。

    时间复杂度$O(Tn^2)$。

    Code:

    #include <cstdio>
    #include <cstring>
    #include <deque>
    using namespace std;
    
    const int N = 1005;
    const int dx[] = {1, 0, -1, 0};
    const int dy[] = {0, 1, 0, -1};
    
    int testCase, n, m, dis[N][N];
    char mp[N][N];
    
    struct Node {
        int x, y, stp;
    
        inline Node(int nowX = 0, int nowY = 0, int nowStp = 0) {
            x = nowX, y = nowY, stp = nowStp;
        }
    
    };
    deque <Node> Q;
    
    inline bool valid(Node now) {
        return now.x >= 1 && now.x <= n && now.y >= 1 && now.y <= m;
    }
    
    int bfs() {    
        if(n == 1 && m == 1) return 0;
        memset(dis, 0x3f, sizeof(dis));
        dis[1][1] = 0;
        Q.clear();    
    
        Q.push_back(Node(1, 1, 0));
        for(; !Q.empty(); ) {
            Node out = Q.front(); Q.pop_front();
            for(int i = 0; i < 4; i++) {
                Node in = Node(out.x + dx[i], out.y + dy[i], 0);
                if(!valid(in)) continue;
                if(dis[in.x][in.y] <= dis[out.x][out.y] + (mp[out.x][out.y] != mp[in.x][in.y]))
                    continue;
                dis[in.x][in.y] = dis[out.x][out.y] + (mp[out.x][out.y] != mp[in.x][in.y]);
                in.stp = dis[in.x][in.y];
                if(in.stp == out.stp) Q.push_front(in);
                else Q.push_back(in);
            }
        }
    }
    
    int main() {
        for(scanf("%d", &testCase); testCase--; ) {
            scanf("%d%d", &n, &m);
            for(int i = 1; i <= n; i++) scanf("%s", mp[i] + 1);
            bfs();
            printf("%d
    ", dis[n][m]);
    
    /*        for(int i = 1; i <= n; i++, printf("
    "))
                for(int j = 1; j <= m; j++)
                    printf("%c ", mp[i][j]);
            
            printf("
    ");
            for(int i = 1; i <= n; i++, printf("
    "))
                for(int j = 1; j <= m; j++)
                    printf("%d ", vis[i][j]);    */
    
        }
        return 0;
    }
    View Code
  • 相关阅读:
    美国大学排名之本科中最用功的学校top15
    PhpStorm (强大的PHP开发环境)2017.3.2 附注册方法
    获取地址栏的URL: PHP JS
    怎么给php下拉框默认选中
    在JS中使用全局变量
    原生和jQuery的ajax用法
    XAMPP重要文件目录及配置
    select获取下拉框的值 下拉框默认选中
    h5 时间控件问题,怎么设置type =datetime-local 的值
    JS截取字符串常用方法详细整理
  • 原文地址:https://www.cnblogs.com/CzxingcHen/p/9797435.html
Copyright © 2011-2022 走看看