結果

問題 No.307 最近色塗る問題多くない?
ユーザー kimiyukikimiyuki
提出日時 2016-03-01 21:55:47
言語 C++11
(gcc 11.4.0)
結果
TLE  
実行時間 -
コード長 2,404 bytes
コンパイル時間 1,221 ms
コンパイル使用メモリ 86,900 KB
実行使用メモリ 13,728 KB
最終ジャッジ日時 2024-09-24 13:13:38
合計ジャッジ時間 7,600 ms
ジャッジサーバーID
(参考情報)
judge1 / judge2
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
6,812 KB
testcase_01 AC 1 ms
6,944 KB
testcase_02 AC 2 ms
6,944 KB
testcase_03 AC 1 ms
6,940 KB
testcase_04 AC 3 ms
6,940 KB
testcase_05 AC 2 ms
6,944 KB
testcase_06 AC 2 ms
6,940 KB
testcase_07 AC 476 ms
6,940 KB
testcase_08 TLE -
testcase_09 -- -
testcase_10 -- -
testcase_11 -- -
testcase_12 -- -
testcase_13 -- -
testcase_14 -- -
testcase_15 -- -
testcase_16 -- -
testcase_17 -- -
testcase_18 -- -
testcase_19 -- -
testcase_20 -- -
testcase_21 -- -
testcase_22 -- -
testcase_23 -- -
testcase_24 -- -
testcase_25 -- -
testcase_26 -- -
testcase_27 -- -
testcase_28 -- -
testcase_29 -- -
testcase_30 -- -
testcase_31 -- -
testcase_32 -- -
testcase_33 -- -
testcase_34 -- -
testcase_35 -- -
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#define repeat(i,n) for (int i = 0; (i) < (n); ++(i))
typedef long long ll;
using namespace std;
struct union_find {
    vector<int> tree;
    explicit union_find(size_t n) : tree(n, -1) {}
    bool is_root(int a) { return tree[a] < 0; }
    int find_root(int a) { return is_root(a) ? a : (tree[a] = find_root(tree[a])); }
    int tree_size(int a) { return - tree[find_root(a)]; }
    void union_tree(int a, int b) {
        a = find_root(a); b = find_root(b);
        if (a != b) {
            if (not (tree_size(a) < tree_size(b))) swap(a,b);
            tree[b] += tree[a];
            tree[a] = b;
        }
    }
    bool is_connected(int a, int b) { return find_root(a) == find_root(b); }
};
int main() {
    int h, w; cin >> h >> w;
    auto ix = [&](int y, int x) { return y*w + x; };
    vector<int> a(h * w); repeat (y,h) repeat (x,w) cin >> a[ix(y,x)];
    union_find t(h * w);
    repeat (y,h) repeat (x,w) {
        if (y+1 < h and a[ix(y,x)] == a[ix(y+1,x)]) t.union_tree(ix(y,x), ix(y+1,x));
        if (x+1 < w and a[ix(y,x)] == a[ix(y,x+1)]) t.union_tree(ix(y,x), ix(y,x+1));
    }
    auto root = [&](int y, int x) { return t.find_root(ix(y,x)); };
    vector<set<int> > g(h * w);
    repeat (y,h) repeat (x,w) {
        if (y+1 < h and a[ix(y,x)] != a[ix(y+1,x)]) {
            g[root(y,x)].insert(root(y+1,x));
            g[root(y+1,x)].insert(root(y,x));
        }
        if (x+1 < w and a[ix(y,x)] != a[ix(y,x+1)]) {
            g[root(y,x)].insert(root(y,x+1));
            g[root(y,x+1)].insert(root(y,x));
        }
    }
    int q; cin >> q;
    repeat (query,q) {
        int y, x, p; cin >> y >> x >> p; -- y; -- x;
        int i = root(y,x);
        if (a[i] == p) continue;
        a[i] = p;
        vector<int> e;
        for (int j : g[i]) {
            t.union_tree(i,j);
            for (int k : g[j]) e.push_back(k);
        }
        sort(e.begin(), e.end());
        e.erase(unique(e.begin(), e.end()), e.end());
        set<int> s(e.begin(), e.end());
        for (int j : g[i]) s.erase(j);
        s.erase(i);
        int k = t.find_root(i);
        g[k] = s;
        for (int j : g[k]) g[j].insert(k);
        a[k] = p;
    }
    repeat (y,h) {
        repeat (x,w) {
            if (x) cout << ' ';
            cout << a[root(y,x)];
        }
        cout << endl;
    }
    return 0;
}
0