zoukankan      html  css  js  c++  java
  • bzoj 2936 [Poi 1999] 降水

    题目传送门

      需要root权限的传送门

    题目大意

      有一个$n imes m$的网格图,每一格都有一个高度。一次降雨过后问最多能积多少水。

      考虑算每一高度能储存的水的量。

      如果小于等于这个高度的格子和边界连通,那么水就会流走,这一部分不能算入答案。

      所以用并查集维护高度小于等于当前高度的格子的连通性。每次答案加已经找到的格子数目减去和边界连通的格子数。

      时间复杂度$O(nm + V)$。(用真·并查集就是这样)

      网上咋一群带个log的做法。想去loj出个加强版。

    Code

     1 /**
     2  * bzoj
     3  * Problem#2936
     4  * Accepted
     5  * Time: 56ms
     6  * Memory: 1688k 
     7  */
     8 #include <bits/stdc++.h>
     9 using namespace std;
    10 typedef bool boolean;
    11 
    12 const int N = 105, V = 10000;
    13 const int mov[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
    14 
    15 typedef class Dsu {
    16     public:
    17         int *f;
    18         int *siz;
    19 
    20         Dsu() {    }
    21         Dsu(int n) {
    22             f = new int[(n + 1)];
    23             siz = new int[(n + 1)];
    24             f[0] = siz[0] = 0; 
    25             for (int i = 1; i <= n; i++)
    26                 f[i] = i;
    27             for (int i = 1; i <= n; i++)
    28                 siz[i] = 1;
    29         }
    30 
    31         int find(int x) {
    32             return (f[x] == x) ? (x) :(f[x] = find(f[x]));
    33         }
    34 
    35         void unit(int x, int y) {
    36             int fx = find(x);
    37             int fy = find(y);
    38             if (fx == fy)
    39                 return;
    40             siz[fy] += siz[fx];
    41             f[fx] = fy;
    42         }
    43 }Dsu;
    44 
    45 int n, m;
    46 Dsu uf;
    47 boolean found[N][N];
    48 vector< pair<int, int> > vs[V + 1];
    49 
    50 int id(int x, int y) {
    51     if (!x || !y || x == n + 1 || y == m + 1)
    52         return 0;
    53     return (x - 1) * m + y;
    54 }
    55 
    56 inline void init() {
    57     scanf("%d%d", &n, &m);
    58     uf = Dsu(n * m);
    59     for (int i = 1; i <= n; i++)
    60         for (int j = 1, h; j <= m; j++) {
    61             scanf("%d", &h);
    62             vs[h].push_back(pair<int, int>(i, j));
    63         }
    64 }
    65 
    66 int cfound = 0, res = 0;
    67 inline void solve() {
    68     int all = n * m;
    69     for (int v = 1; v <= V && uf.siz[uf.find(0)] != all; v++) {
    70         for (int j = 0; j < (signed) vs[v].size(); j++) {
    71             int x = vs[v][j].first, y = vs[v][j].second;
    72             found[x][y] = true, cfound++;
    73             for (int k = 0; k < 4; k++) {
    74                 int nx = x + mov[k][0], ny = y + mov[k][1], nxid = id(nx, ny);
    75                 if (!nxid || found[nx][ny])
    76                     uf.unit(nxid, id(x, y));
    77             }
    78         }
    79         res += cfound - uf.siz[uf.find(0)];
    80     }
    81     printf("%d", res);
    82 }
    83 
    84 int main() {
    85     init();
    86     solve();
    87     return 0;
    88 }
  • 相关阅读:
    html5的跨域处理
    file表单提交异步模拟
    Bigpipe :bigpipe的了解之2
    javascript获取指定父元素
    javascript淡入淡出的效果轮换转播
    IE下,动态创建的iframe在异步提交时会跳转的问题的解决
    javascriptIE不支持table的innerHTML解决方案
    javascript删除元素所引起的 对于NodeList的理解
    javascript淡入淡出的效果轮换转播后续
    数据加载的bigpipe
  • 原文地址:https://www.cnblogs.com/yyf0309/p/9424730.html
Copyright © 2011-2022 走看看