zoukankan      html  css  js  c++  java
  • arc112d

    arc112d

    大意

    略...

    思路

    乱搞,很难证明(

    显然,任意一个点都可以到达四周,或者说左下角那一个点。

    所以,只要能从左下角那一个点,到达其他所有的点,那么就满足题意了。

    我们将行和列抽象为两个互不相关的并查集。

    如果两个 '#' 在同一行,我们就将它们对应的列并查集链接,

    如果在同一列,就将行并查集链接。

    含义为,两列(行) 的点可以互相到达。

    注意,首列和尾列,首行和尾行开始就应该链接。

    如果某个 '#' 在第1行或者第h行,那么我们要将其对应的列和首列链接,想一下图就能发现。

    如果某个 '#' 在第1列或者第w列,那么我们要将其对应的行和首行链接。

    如果每行间都能互相到达,或者每列间都能互相到达,那么就是满足题意的。

    所以,记 (c_1) 为行并查集独立集个数, (c_2) 为列并查集独立集个数。

    答案为 (min(c_1, c_2) -1)

    (因为,添加一个 '#' 只能将两个独立集合并)

    代码

    #include <map>
    #include <set>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <vector>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    #define ll long long
    #define ull unsigned long long
    #define cint const int&
    #define Pi acos(-1)
    
    const int mod = 1e9+7;
    const int inf_int = 0x7fffffff;
    const ll inf_ll = 0x7fffffffffffffff;
    const double ept = 1e-9;
    
    int h, w;
    int bcj[2][1010];
    int row[1001], col[1001];
    
    int fd(cint x, bool st) {
        return bcj[st][x] == x ? x : bcj[st][x] = fd(bcj[st][x], st);
    }
    
    int main() {
        ios::sync_with_stdio(false);
        int s = -1, ss = -1;
        cin >> h >> w;
        char a;
        for(int i=1; i<=h; i++) bcj[0][i] = i;
        for(int i=1; i<=w; i++) bcj[1][i] = i;
        bcj[1][w] = 1; bcj[0][h] = 1;
        for(int i=1; i<=h; i++)
            for(int j=1; j<=w; j++) {
                cin >> a;
                if(a == '#') {
                    if(i == 1 || i == h) bcj[1][fd(bcj[1][j], 1)] = fd(bcj[1][1], 1);
                    else {
                        if(row[i] != 0) bcj[1][fd(bcj[1][j], 1)] = fd(bcj[1][row[i]], 1);
                        row[i] = j;
                    }
                    if(j == 1 || j == w) bcj[0][fd(bcj[0][i], 0)] = fd(bcj[0][1], 0);
                    else {
                        if(col[j] != 0) bcj[0][fd(bcj[0][i], 0)] = fd(bcj[0][col[j]], 0);
                        col[j] = i;
                    }
    
                }
            }
        int tmp = 0;
        for(int i=1; i<=w; i++)
            if(bcj[1][i] == i) ++tmp;
        int tmp1 = 0;
        for(int i=1; i<=h; i++)
            if(bcj[0][i] == i) ++tmp1;
        cout << min(tmp1, tmp) - 1 << endl;
        return 0;
    }
    
  • 相关阅读:
    Android Interactive Animation
    Android 笔记
    java 从零开始 第三天
    RGB颜色查询对照表
    Android TextView文字过多时通过滚动条显示多余内容
    Android系统字体规范
    Android 动画之TranslateAnimation应用详解
    Python--day69--ORM的F查询和Q查询
    Python--day69--ORM聚合查询和分组查询
    Python--day69--ORM正反向查找(外键)
  • 原文地址:https://www.cnblogs.com/ullio/p/14561509.html
Copyright © 2011-2022 走看看