結果

問題 No.416 旅行会社
ユーザー dyktr_06dyktr_06
提出日時 2022-12-09 18:20:11
言語 C++14
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 484 ms / 4,000 ms
コード長 2,681 bytes
コンパイル時間 2,358 ms
コンパイル使用メモリ 181,336 KB
実行使用メモリ 23,624 KB
最終ジャッジ日時 2024-12-14 21:17:24
合計ジャッジ時間 7,672 ms
ジャッジサーバーID
(参考情報)
judge4 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 176 ms
17,604 KB
testcase_01 AC 2 ms
5,248 KB
testcase_02 AC 2 ms
5,248 KB
testcase_03 AC 2 ms
5,248 KB
testcase_04 AC 2 ms
5,248 KB
testcase_05 AC 2 ms
5,248 KB
testcase_06 AC 2 ms
5,248 KB
testcase_07 AC 2 ms
5,248 KB
testcase_08 AC 6 ms
5,248 KB
testcase_09 AC 22 ms
5,248 KB
testcase_10 AC 198 ms
17,600 KB
testcase_11 AC 198 ms
17,480 KB
testcase_12 AC 196 ms
16,960 KB
testcase_13 AC 181 ms
17,476 KB
testcase_14 AC 480 ms
23,620 KB
testcase_15 AC 481 ms
23,616 KB
testcase_16 AC 471 ms
23,616 KB
testcase_17 AC 484 ms
23,624 KB
testcase_18 AC 473 ms
23,624 KB
testcase_19 AC 297 ms
17,220 KB
testcase_20 AC 289 ms
17,088 KB
権限があれば一括ダウンロードができます
コンパイルメッセージ
main.cpp: In function 'int main()':
main.cpp:77:14: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17' [-Wc++17-extensions]
   77 |         auto [a, b] = p1[i];
      |              ^
main.cpp:83:14: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17' [-Wc++17-extensions]
   83 |         auto [a, b] = p2[i];
      |              ^

ソースコード

diff #

#define PROBLEM "https://yukicoder.me/problems/no/416"
#include <bits/stdc++.h>
using namespace std;

struct PersistentUnionFind{
    int now;
    vector<int> par, rank, time;
    vector<vector<pair<int, int>>> num;
    const int INF = 1 << 30;

    PersistentUnionFind(const int &N) : par(N), rank(N), time(N), num(N){
        now = 0;
        for(int i = 0; i < N; ++i){
            par[i] = i;
            num[i].emplace_back(0, 1);
        }
        fill(rank.begin(), rank.begin() + N, 0);
        fill(time.begin(), time.begin() + N, INF);
    }

    int root(const int &x, const int &t){
        if(t < time[x]) return x;
        return root(par[x], t);
    }

    void unite(const int &x, const int &y){
        ++now;

        int rx = root(x, now);
        int ry = root(y, now);
        if(rx == ry) return;

        if(rank[rx] < rank[ry]) swap(rx, ry);
        num[rx].emplace_back(now, size(rx, now) + size(ry, now));

        par[ry] = rx;
        time[ry] = now;
        if(rank[rx] == rank[ry]) ++rank[rx];
    }

    bool same(const int &x, const int &y, const int &t){
        int rx = root(x, t);
        int ry = root(y, t);
        return rx == ry;
    }

    int size(const int &x, const int &t){
        int rx = root(x, t);

        int ok = 0, ng = num[rx].size();
        while(abs(ok - ng) > 1){
            int mid = (ok + ng) / 2;
            if(num[rx][mid].first <= t){
                ok = mid;
            }else{
                ng = mid;
            }
        }
        return num[rx][ok].second;
    }
};
int main(){
    int n, m, q; cin >> n >> m >> q;
    PersistentUnionFind tree(n);
    vector<pair<int, int>> p1, p2;
    set<pair<int, int>> s;
    for(int i = 0; i < m; i++){
        int a, b; cin >> a >> b; a--; b--;
        p1.emplace_back(a, b);
    }
    for(int i = 0; i < q; i++){
        int c, d; cin >> c >> d; c--; d--;
        p2.emplace_back(c, d);
        s.insert({c, d});
    }
    for(int i = 0; i < m; i++){
        auto [a, b] = p1[i];
        if(s.find({a, b}) == s.end()){
            tree.unite(a, b);
        }
    }
    for(int i = q - 1; i >= 0; i--){
        auto [a, b] = p2[i];
        tree.unite(a, b);
    }
    for(int i = 1; i < n; i++){
        if(!tree.same(0, i, m)){
            cout << 0 << "\n";
            continue;
        }else if(tree.same(0, i, m - q)){
            cout << -1 << "\n";
            continue;
        }
        int ok = m, ng = m - q;
        while(abs(ok - ng) > 1){
            int mid = (ok + ng) / 2;
            if(tree.same(0, i, mid)){
                ok = mid;
            }else{
                ng = mid;
            }
        }
        cout << m - ok + 1 << "\n";
    }
}
0