結果

問題 No.416 旅行会社
ユーザー はむ吉🐹はむ吉🐹
提出日時 2016-08-27 20:48:07
言語 C++11
(gcc 11.4.0)
結果
AC  
実行時間 615 ms / 4,000 ms
コード長 3,682 bytes
コンパイル時間 1,774 ms
コンパイル使用メモリ 99,192 KB
実行使用メモリ 49,760 KB
最終ジャッジ日時 2023-08-21 09:54:34
合計ジャッジ時間 9,538 ms
ジャッジサーバーID
(参考情報)
judge11 / judge12
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 283 ms
36,692 KB
testcase_01 AC 2 ms
4,376 KB
testcase_02 AC 2 ms
4,380 KB
testcase_03 AC 2 ms
4,380 KB
testcase_04 AC 2 ms
4,380 KB
testcase_05 AC 1 ms
4,380 KB
testcase_06 AC 2 ms
4,380 KB
testcase_07 AC 3 ms
4,380 KB
testcase_08 AC 8 ms
4,384 KB
testcase_09 AC 35 ms
6,636 KB
testcase_10 AC 309 ms
36,636 KB
testcase_11 AC 297 ms
39,684 KB
testcase_12 AC 306 ms
39,684 KB
testcase_13 AC 284 ms
39,744 KB
testcase_14 AC 588 ms
46,592 KB
testcase_15 AC 605 ms
48,244 KB
testcase_16 AC 605 ms
49,760 KB
testcase_17 AC 615 ms
48,528 KB
testcase_18 AC 593 ms
47,260 KB
testcase_19 AC 457 ms
40,368 KB
testcase_20 AC 439 ms
37,592 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <algorithm>
#include <ciso646>
#include <cstdlib>
#include <iostream>
#include <numeric>
#include <set>
#include <vector>
#include <unordered_set>
#include <utility>


typedef std::pair<int, int> Edge;


class DisjointDataStructure {
public:
    DisjointDataStructure(int number_of_nodes) {
        par = std::vector<int>(number_of_nodes);
        std::iota(par.begin(), par.end(), 0);
        rank = std::vector<int>(number_of_nodes);
        groups = std::vector<std::unordered_set<int>>(number_of_nodes);
        for (int i = 0; i < number_of_nodes; i++)
        {
            groups[i].insert(i);
        }
    }
    int root(int node) {
        if (par[node] == node)
        {
            return node;
        }
        else
        {
            return par[node] = root(par[node]);
        }
    }
    inline bool inTheSameSet(int node1, int node2) {
        return root(node1) == root(node2);
    }
    inline std::unordered_set<int> group(int x) {
        return groups[root(x)];
    }
    void unite(int node1, int node2) {
        auto x = root(node1);
        auto y = root(node2);
        if (x == y)
        {
            return;
        }
        else if (rank[x] < rank[y])
        {
            par[x] = y;
            groups[y].insert(groups[x].begin(), groups[x].end());
            groups[x].clear();
        }
        else
        {
            par[y] = x;
            groups[x].insert(groups[y].begin(), groups[y].end());
            groups[y].clear();
            if (rank[x] == rank[y])
            {
                rank[x]++;
            }
        }
    }
private:
    std::vector<int> par;
    std::vector<int> rank;
    std::vector<std::unordered_set<int>> groups;
};


std::vector<int> solve(int n, int q, const std::set<Edge>& all_edges,
    const std::vector<Edge>& removed_edges) {
    auto removed_edges_set = std::set<Edge>(removed_edges.begin(), removed_edges.end());
    auto uf = DisjointDataStructure(n);
    constexpr int root = 0;
    auto con_time = std::vector<int>(n);
    for (const auto& edge : all_edges)
    {
        if (removed_edges_set.count(edge) == 0)
        {
            uf.unite(edge.first, edge.second);
        }
    }
    for (int i = 1; i < n; i++)
    {
        if (uf.inTheSameSet(root, i))
        {
            con_time[i] = -1;
        }
    }
    for (int i = q - 1; i >= 0; i--)
    {
        auto source = removed_edges[i].first;
        auto dest = removed_edges[i].second;
        if (not uf.inTheSameSet(source, dest))
        {
            auto bs = uf.inTheSameSet(root, source);
            auto bd = uf.inTheSameSet(root, dest);
            if (bs or bd)
            {
                if (bd)
                {
                    std::swap(source, dest);
                }
                for (const auto& v : uf.group(dest))
                {
                    con_time[v] = i + 1;
                }
            }
            uf.unite(source, dest);
        }
    }
    return con_time;
}


int main() {
    std::cin.tie(nullptr);
    std::ios::sync_with_stdio(false);
    int n, m, q;
    std::cin >> n >> m >> q;
    std::set<Edge> all_edges;
    for (int i = 0; i < m; i++)
    {
        int a, b;
        std::cin >> a >> b;
        a--;
        b--;
        all_edges.insert(std::make_pair(a, b));
    }
    std::vector<Edge> removed_edges;
    for (int i = 0; i < q; i++)
    {
        int c, d;
        std::cin >> c >> d;
        c--;
        d--;
        removed_edges.push_back(std::make_pair(c, d));
    }
    auto con_time = solve(n, q, all_edges, removed_edges);
    for (int i = 1; i < n; i++)
    {
        std::cout << con_time[i] << std::endl;
    }
    return EXIT_SUCCESS;
}
0