結果

問題 No.3093 Safe Infection
ユーザー miya145592
提出日時 2025-04-06 17:06:12
言語 C++23
(gcc 13.3.0 + boost 1.87.0)
結果
TLE  
実行時間 -
コード長 2,775 bytes
コンパイル時間 1,990 ms
コンパイル使用メモリ 124,616 KB
実行使用メモリ 18,420 KB
最終ジャッジ日時 2025-04-06 17:06:25
合計ジャッジ時間 11,180 ms
ジャッジサーバーID
(参考情報)
judge2 / judge5
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 44 TLE * 1 -- * 25
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;

class UnionFind {
public:
    vector<int> par, rank, siz;
    int cnt;

    UnionFind(int n) {
        par.assign(n, -1);
        rank.assign(n, 0);
        siz.assign(n, 1);
        cnt = n;
    }

    int root(int x) {
        if (par[x] == -1) return x;
        return par[x] = root(par[x]);
    }

    bool issame(int x, int y) {
        return root(x) == root(y);
    }

    bool unite(int x, int y) {
        int px = root(x);
        int py = root(y);
        if (px == py) return false;
        if (rank[px] < rank[py]) swap(px, py);
        par[py] = px;
        if (rank[px] == rank[py]) rank[px]++;
        siz[px] += siz[py];
        cnt--;
        return false;
    }

    int count() {
        return cnt;
    }

    int size(int x) {
        return siz[root(x)];
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int N, M, K;
    cin >> N >> M >> K;
    vector<int> A(N);
    for (int i = 0; i < N; ++i) {
        cin >> A[i];
    }

    // G[u] = {(A[v], v)}
    vector<vector<pair<int, int>>> G(N);
    for (int i = 0; i < M; ++i) {
        int u, v;
        cin >> u >> v;
        --u; --v;
        G[u].emplace_back(A[v], v);
        G[v].emplace_back(A[u], u);
    }

    UnionFind UF(N);
    vector<pair<int, int>> dp;
    for (int i = 0; i < N; ++i) {
        dp.emplace_back(A[i], i);
    }

    // Pythonの dp.sort(reverse=True)
    sort(dp.rbegin(), dp.rend());

    while (dp.size() > 1) {
        auto [a, i] = dp.back();
        dp.pop_back();
        int ri = UF.root(i);

        // G[ri] をヒープとして扱うために make_heap を使う
        auto& gi = G[ri];
        make_heap(gi.begin(), gi.end(), greater<>());
        if (gi.empty()) continue;

        pop_heap(gi.begin(), gi.end(), greater<>());
        auto [s, j] = gi.back();
        gi.pop_back();

        int rj = UF.root(j);
        if (s - a > K) {
            cout << "No\n";
            return 0;
        }

        UF.unite(i, j);
        int r = UF.root(i);

        if (G[ri].size() < G[rj].size()) {
            auto& gj = G[rj];
            make_heap(gj.begin(), gj.end(), greater<>());
            if (!gj.empty()) {
                pop_heap(gj.begin(), gj.end(), greater<>());
                gj.pop_back();
            }

            for (auto& g : G[ri]) {
                G[rj].push_back(g);
            }
            G[ri].clear();
            G[r] = G[rj];
        } else {
            for (auto& g : G[rj]) {
                if (UF.root(g.second) == ri) continue;
                G[ri].push_back(g);
            }
            G[rj].clear();
            G[r] = G[ri];
        }
    }

    cout << "Yes\n";
    return 0;
}
0