zoukankan      html  css  js  c++  java
  • F. Super Jaber (多源BFS)

    题目:传送门

    题意: 有n * m个城市,每个城市都有一个颜色,共有 k 种颜色,也就是每个城市的颜色只能是 1 ~ k 的某个数字。

           然后,有q次询问,每次询问给你 x1, y1, x2, y2;问你从(x1, y1)到(x2, y2)的最少操作数。

           操作有两种: 1、 你可以移动到你当前位置的上下左右,只要不越界。

                  2、你可以移动到任意和你当前所在的位置颜色相同的位置。

       1 <= n, m <= 1000,  k <= min(40, n * m);

    题解: 多源dfs, dis[ col ][ i ][ j ] 表示颜色为 col 的点 到 (i, j) 这个点的最少操作。

        

    #include <bits/stdc++.h>
    #define LL long long
    #define mem(i, j) memset(i, j, sizeof(i))
    #define rep(i, j, k) for(int i = j; i <= k; i++)
    #define dep(i, j, k) for(int i = k; i >= j; i--)
    #define pb push_back
    #define make make_pair
    #define INF INT_MAX
    #define inf LLONG_MAX
    #define PI acos(-1)
    using namespace std;
    
    const int N = 510;
    
    int n, m, k;
    vector < pair<int, int> > G[50];
    int dis[50][1005][1005], vis[50];
    queue < pair<int, int> > Q;
    int xx[4] = {0, 0, -1, 1};
    int yy[4] = {1, -1, 0, 0};
    int a[1005][1005];
    
    void bfs(int col) {
        for(pair<int, int> v : G[col]) {
            dis[col][v.first][v.second] = 0;
            Q.push(v);
        }
        rep(i, 1, k) vis[i] = 0;
        while(!Q.empty()) {
            pair <int ,int> tmp = Q.front(); Q.pop();
            int x = tmp.first, y = tmp.second;
            rep(i, 0, 3) {
                int nx = x + xx[i];
                int ny = y + yy[i];
                if(nx < 1 || nx > n || ny < 1 || ny > m || dis[col][nx][ny] != -1) continue;
                dis[col][nx][ny] = dis[col][x][y] + 1;
                Q.push(make(nx, ny));
            }
            if(!vis[a[x][y]]) {
                vis[a[x][y]] = 1;
                for(pair <int, int> v : G[a[x][y]]) {
                    if(dis[col][v.first][v.second] == -1) {
                        dis[col][v.first][v.second] = dis[col][x][y] + 1;
                        Q.push(v);
                    }
                }
            }
        }
    }
    int main() {
        scanf("%d %d %d", &n, &m, &k);
        rep(i, 1, n) rep(j, 1, m) scanf("%d", &a[i][j]), G[a[i][j]].pb(make(i, j));
        mem(dis, -1);
        rep(i, 1, k) bfs(i);
        int q; scanf("%d", &q);
        while(q--) {
            int x1, x2, y1, y2;
            scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
            int ans = abs(y1 - y2) + abs(x2 - x1);
            rep(i, 1, k) ans = min(ans, dis[i][x1][y1] + dis[i][x2][y2] + 1);
            printf("%d
    ", ans);
        }
        return 0;
    }
    View Code
    一步一步,永不停息
  • 相关阅读:
    如何查看openssl支持的所有TLS/SSL版本
    讲故事,学(AHK)设计模式—观察者模式
    React Hooks 详解 【近 1W 字】+ 项目实战
    为什么要在函数组件中使用React.memo?
    js防抖函数
    JS 深度优先遍历与广度优先遍历 实现查找
    你不知道的 requestIdleCallback
    RE:ゼロから始める文化課生活
    开学考小记 & 新生活的开始
    JS中:数组和对象的区别,以及遍历数组和遍历对象的区别
  • 原文地址:https://www.cnblogs.com/Willems/p/12308289.html
Copyright © 2011-2022 走看看