zoukankan      html  css  js  c++  java
  • P1514 引水入城

    中文题

    想法:

    首先需要一个结论: 如果有解,我们每个点覆盖的城市(线段)一定是连续的。因为如果不是连续,我么们可以很容易的证明这个点无法到达(它所在联通块边界一定高于相邻点)

    所以我们利用记忆话搜索的方式预处理出所有点可以到达沙漠的一个连续区间的 L 和 R 

    那么这个问题就变成了最小线段覆盖问题了

    #pragma GCC optimize(3,"Ofast","inline")//O3优化
    #pragma GCC optimize(2)//O2优化
    #include <algorithm>
    #include <string>
    #include <string.h>
    #include <vector>
    #include <map>
    #include <stack>
    #include <set>
    #include <queue>
    #include <math.h>
    #include <cstdio>
    #include <iomanip>
    #include <time.h>
    #include <bitset>
    #include <cmath>
    #include <sstream>
    #include <iostream>
    #include <cstring>
    
    #define LL long long
    #define ls nod<<1
    #define rs (nod<<1)+1
    #define pii pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define INF 0x3f3f3f3f
    #define max(a,b) (a>b?a:b)
    #define min(a,b) (a<b?a:b)
    
    const double eps = 1e-10;
    const int maxn = 500 + 10;
    const LL mod = 998244353;
    
    int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;}
    using namespace std;
    
    int mpp[maxn][maxn];
    int vis[maxn][maxn];
    int l[maxn][maxn],r[maxn][maxn];
    int n,m;
    int dir[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
    
    void dfs(int x,int y) {
        vis[x][y] = 1;
        for (int i = 0; i < 4; i++) {
            int xx = x + dir[i][0];
            int yy = y + dir[i][1];
            if (xx < 1 || xx > n || yy < 1 || yy > m || mpp[xx][yy] >= mpp[x][y]) {
                continue;
            }
            if (!vis[xx][yy]) {
                dfs(xx, yy);
            }
            l[x][y] = min(l[x][y], l[xx][yy]);
            r[x][y] = max(r[x][y], r[xx][yy]);
        }
    }
    
    
    int main() {
        ios::sync_with_stdio(0);
        cin >> n >> m;
        memset(l,INF, sizeof(l));
        memset(r,0, sizeof(r));
        for (int i = 1;i <= n;i++) {
            for (int j = 1;j <= m;j++) {
                cin >> mpp[i][j];
                l[n][j] = r[n][j] = j;
            }
        }
        for (int i = 1;i <= m;i++) {
            if (!vis[1][i])
                dfs(1,i);
        }
        bool fl = false;
        int cnt = 0;
        for (int i = 1;i <= m;i++) {
            if (!vis[n][i]) {
                fl = true;
                cnt++;
            }
        }
        if (fl) {
            cout << 0 << endl;
            cout << cnt << endl;
            return 0;
        }
        int lef = 1;
        while (lef <= m) {
            int maxr = 0;
            for (int i = 1;i <= m;i++) {
                if (l[1][i] <= lef)
                    maxr = max(maxr,r[1][i]);
            }
            cnt++;
            lef = maxr + 1;
        }
        cout << 1 << endl;
        cout << cnt << endl;
        return 0;
    }
  • 相关阅读:
    让IE6 IE7 IE8 IE9 IE10 IE11支持Bootstrap的解决方法
    检测到有潜在危险的 Request.Form 值
    jQuery校验
    C#客户端的异步操作
    泛型(一)
    c#面试题汇总
    多线程(下)
    多线程(上)
    线程篇(二)
    线程篇(一)
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/12554503.html
Copyright © 2011-2022 走看看