zoukankan      html  css  js  c++  java
  • SPOJ KATHTHI

    题意

    给出一个$n imes m$的网格,每个位置有一个小写字母,初始在$(1, 1)$,每次可以向上下左右走,问走到$(n, m)$的最小花费

    设$(x, y)$为当前位置,$(nx, ny)$为下一位置。$s[x][y]$表示$(x, y)$位置的字符。

    若$s[x][y] = s[nx][ny]$,则移动的花费为$0$,否则花费为$1$

    Sol

    01BFS的裸题,感觉这个点子还是很妙的

    01BFS可以在$O(n+m)$求出边权只有$0 / 1$的最短路

    我们维护一个双端队列,如当前可以进行松弛那么就进行更新,更新完后判断一下,若边权为$1$,则在队尾加入下一个点,否则在队首加入下一个点

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    //#define int long long 
    using namespace std;
    const int MAXN = 1001;
    inline int read() {
        char c = getchar(); int x = 0, f = 1;
        while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x * f;
    }
    int N, M;
    struct Node {
        int x, y, s;
    };
    deque<Node> q;
    int dis[MAXN][MAXN], xx[] = {-1, +1, 0, 0}, yy[] = {0, 0, -1, +1};
    char s[MAXN][MAXN];
    void OneZeroBFS() {
        q.push_back((Node) {1, 1, 0});
        while(!q.empty()) {
            Node p = q.front(); q.pop_front();
            for(int i = 0; i < 4; i++) {
                int wx = p.x + xx[i], wy = p.y + yy[i];
                int w = (s[wx][wy] != s[p.x][p.y]);
                if(dis[wx][wy] > dis[p.x][p.y] + w && (wx > 0 && wy > 0 && wx <= N && wy <= M))
                    dis[wx][wy] = dis[p.x][p.y] + w,
                    w == 1 ? q.push_back((Node) {wx, wy, w}) : q.push_front((Node) {wx, wy, w});
            }
        }
    }
    main() {
        int QwQ = read();
        while(QwQ--) {
            memset(dis, 0xf, sizeof(dis));
            dis[1][1] = 0;
            N = read(); M = read();
            for(int i = 1; i <= N; i++)    
                scanf("%s", s[i] + 1);
            OneZeroBFS();
            printf("%d
    ", dis[N][M]);
        }
        return 0;
    }
    /*
    4
    2 2
    aa
    aa
    2 3
    abc
    def
    6 6
    akaccc
    aaacfc
    amdfcc
    aokhdd
    zyxwdp
    zyxwdd
    5 5
    abbbc
    abacc
    aaacc
    aefci
    cdgdd
    */
  • 相关阅读:
    MyBatis入门基础
    复制复杂链表
    二叉树中和为某一值的所有路径
    树的层次遍历
    Statement, PreparedStatement和CallableStatement的区别
    JSP有哪些动作?
    latex 输入矩阵
    Struts简单入门实例
    在Eclipse里面配置Struts2
    Windows使用Github
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/9403513.html
Copyright © 2011-2022 走看看