zoukankan      html  css  js  c++  java
  • 洛谷 P6833 [Cnoi2020]雷雨

    思路

    没想到思路真的可以这么暴力……

    可以想到,这题其实就是找一个点满足这个点到题目要求的三个点的最短路之和最小(剔除重复部分),所以直接用 (Dijkstra) 求出三个点到每个点的最短路,然后 (O(N^2)) 扫描每个点找出满足上述条件的点即可。

    注意输入的矩阵第一行是 (n) 然后递减,所以如果是从 (1) 开始输入的需要把题目中 (1)(n) 替换。

    gyh 说这题卡空间,但是我写的只花了 40MB 啊qwq(然后知道似乎他建图了我没建图)

    代码

    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <vector>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define ll long long
    using namespace std;
    
    const int A = 1e3 + 11;
    const int B = 1e6 + 11;
    const int mod = 1e9 + 7;
    const int inf = 0x3f3f3f3f;
    const int dx[4] = {0, 0, 1, -1};
    const int dy[4] = {1, -1, 0, 0};
    
    inline int read() {
      char c = getchar();
      int x = 0, f = 1;
      for ( ; !isdigit(c); c = getchar()) if (c == '-') f = -1;
      for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
      return x * f;
    }
    
    bool vis[A][A];
    int n, m, a, b, c;
    ll dis[3][A][A], map[A][A];
    
    struct node {
      int x, y;
      ll val;
      bool operator < (const node &b) const {
        return val > b.val;
      }
    };
    
    inline void Dij(int sx, int sy, int tag) {
      priority_queue <node> Q;
      memset(dis[tag], inf, sizeof(dis[tag]));
      memset(vis, 0, sizeof(vis));
      dis[tag][sx][sy] = map[sx][sy];
      Q.push((node){ sx, sy, dis[tag][sx][sy] });
      while (!Q.empty()) {
        int x = Q.top().x, y = Q.top().y; Q.pop();
        if (vis[x][y]) continue;
        vis[x][y] = 1;
        for (int i = 0; i < 4; i++) {
          int bx = x + dx[i], by = y + dy[i];
          if (bx > n || bx < 1 || by > m || by < 1) continue;
          if (dis[tag][bx][by] > dis[tag][x][y] + map[bx][by]) {
            dis[tag][bx][by] = dis[tag][x][y] + 1ll * map[bx][by];
            Q.push((node){ bx, by, dis[tag][bx][by] });
          }
        }
      }
    }
    
    int main() {
      n = read(), m = read(), a = read(), b = read(), c = read();
      for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++) map[i][j] = read();
      Dij(1, a, 0);
      Dij(n, b, 1);
      Dij(n, c, 2);
      ll ans = 1e18;
      for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++) {
          ans = min(ans, dis[0][i][j] + dis[1][i][j] + dis[2][i][j] - 2 * map[i][j]);
        }
      cout << ans << '
    ';
      return 0;
    }
    
  • 相关阅读:
    深入Activity生命周期(一)
    android APK 中英文对比(转)
    android中获得系统语言
    mime Contenttype(http head)(转)
    activity设置全屏
    Activity常用知识
    关于这次数学建模
    排列组合
    hdu 1003 笔记
    杂想
  • 原文地址:https://www.cnblogs.com/loceaner/p/13706242.html
Copyright © 2011-2022 走看看