結果
問題 | No.416 旅行会社 |
ユーザー |
|
提出日時 | 2017-12-31 13:53:07 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 576 ms / 4,000 ms |
コード長 | 4,857 bytes |
コンパイル時間 | 2,869 ms |
コンパイル使用メモリ | 222,124 KB |
最終ジャッジ日時 | 2025-01-05 06:49:16 |
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 21 |
ソースコード
#include <bits/stdc++.h>using namespace std;template <typename T>vector<T> Vec(int n, T v){return vector<T>(n, v);}template <class... Args>auto Vec(int n, Args... args){auto val = Vec(args...);return vector<decltype(val)>(n, move(val));}template <typename Data, typename Checker>void ParallelBinarySearch(const vector<Data>& queries, Checker& checker, const int inf, const int sup, vector<int>& ans){const int Q = queries.size();ans.resize(Q, -1);using Query = pair<Data, int>;struct Qset {int l;int r;vector<Query> query;};vector<Qset> data{Qset{inf, sup, vector<Query>(Q)}};for (int i = 0; i < Q; i++) {data[0].query[i] = make_pair(queries[i], i);}for (int d = 0;; d++) {if (data.empty()) {break;}vector<Qset> next;checker.initialize();int pos = 0;for (const auto& dat : data) {const int inf = dat.l;const int sup = dat.r;const int mid = (inf + sup) / 2;Qset former{inf, mid, vector<Query>{}};Qset latter{mid + 1, sup, vector<Query>{}};for (; pos < mid; pos++) {checker.update(pos);}if (inf >= sup - 1) {for (const auto& e : dat.query) {if (checker.check(e.first)) {ans[e.second] = inf;} else if (inf == sup - 1) {latter.query.push_back(e);}}} else {for (const auto& e : dat.query) {if (checker.check(e.first)) {former.query.push_back(e);} else {latter.query.push_back(e);}}}if (not former.query.empty()) {next.push_back(former);}if (not latter.query.empty()) {next.push_back(latter);}}data = next;}}class DisjointSets{public:DisjointSets(const int v){m_parent.resize(v);m_rank.resize(v);m_size.resize(v);for (int i = 0; i < v; i++) {m_parent[i] = i;m_rank[i] = 0;m_size[i] = 1;}}bool same(const int a, const int b){return find(a) == find(b);}int find(const int a){if (m_parent[a] == a) {return a;} else {return m_parent[a] = find(m_parent[a]);}}void unite(const int a_, const int b_){const int a = find(a_);const int b = find(b_);if (a == b) {return;}if (m_rank[a] > m_rank[b]) {m_parent[b] = a;m_size[a] += m_size[b];} else {m_parent[a] = b;m_size[b] += m_size[a];}if (m_rank[a] == m_rank[b]) {m_rank[b]++;}}int getSize(const int a){return m_size[m_parent[a]];}private:vector<int> m_parent;vector<int> m_rank;vector<int> m_size;};int N;using P = pair<int, int>;vector<P> edge;using Data = int;// Checker::initialize() => void// Checker::update(int pos) => void// Checker::check(const Data&) => boolstruct Checker {Checker(const DisjointSets& org) : orig{org}, uf{N} {}void initialize(){uf = orig;}void update(const int pos){const int u = edge[pos].first;const int v = edge[pos].second;uf.unite(u, v);}bool check(const Data& d){return uf.same(0, d);}DisjointSets orig;DisjointSets uf;};int main(){cin.tie(0);ios::sync_with_stdio(false);cin >> N;int M, Q;cin >> M >> Q;set<P> orig;for (int i = 0; i < M; i++) {int a, b;cin >> a >> b;a--, b--;if (a > b) {swap(a, b);}orig.insert({a, b});}for (int i = 0; i < Q; i++) {int c, d;cin >> c >> d;c--, d--;if (c > d) {swap(c, d);}edge.push_back({c, d});orig.erase({c, d});}DisjointSets uf(N);for (const auto& e : orig) {uf.unite(e.first, e.second);}reverse(edge.begin(), edge.end());Checker checker(uf);vector<int> ans;vector<Data> queries(N - 1);for (int i = 1; i < N; i++) {queries[i - 1] = i;}ParallelBinarySearch(queries, checker, 0, Q, ans);for (int i = 0; i < N - 1; i++) {cout << (ans[i] == -1 ? 0 : ans[i] == 0 ? -1 : Q + 1 - ans[i]) << endl;}return 0;}