結果
問題 | No.416 旅行会社 |
ユーザー | kimiyuki |
提出日時 | 2016-08-26 23:13:07 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 593 ms / 4,000 ms |
コード長 | 2,487 bytes |
コンパイル時間 | 1,181 ms |
コンパイル使用メモリ | 95,892 KB |
実行使用メモリ | 26,300 KB |
最終ジャッジ日時 | 2024-05-08 14:57:58 |
合計ジャッジ時間 | 8,170 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 292 ms
19,584 KB |
testcase_01 | AC | 2 ms
5,376 KB |
testcase_02 | AC | 1 ms
5,376 KB |
testcase_03 | AC | 2 ms
5,376 KB |
testcase_04 | AC | 2 ms
5,376 KB |
testcase_05 | AC | 2 ms
5,376 KB |
testcase_06 | AC | 2 ms
5,376 KB |
testcase_07 | AC | 3 ms
5,376 KB |
testcase_08 | AC | 7 ms
5,376 KB |
testcase_09 | AC | 34 ms
5,376 KB |
testcase_10 | AC | 301 ms
19,584 KB |
testcase_11 | AC | 321 ms
19,612 KB |
testcase_12 | AC | 328 ms
19,584 KB |
testcase_13 | AC | 287 ms
19,628 KB |
testcase_14 | AC | 542 ms
25,984 KB |
testcase_15 | AC | 585 ms
25,856 KB |
testcase_16 | AC | 593 ms
26,024 KB |
testcase_17 | AC | 562 ms
25,984 KB |
testcase_18 | AC | 565 ms
26,300 KB |
testcase_19 | AC | 407 ms
19,476 KB |
testcase_20 | AC | 404 ms
19,584 KB |
ソースコード
#include <iostream> #include <vector> #include <set> #include <functional> #include <cassert> #define repeat(i,n) for (int i = 0; (i) < (n); ++(i)) #define repeat_from(i,m,n) for (int i = (m); (i) < (n); ++(i)) #define repeat_reverse(i,n) for (int i = (n)-1; (i) >= 0; --(i)) using namespace std; template <typename T> struct disjoint_sets { // with data vector<int> xs; vector<T> data; function<void (T &, T &)> append; template <typename F> disjoint_sets(size_t n, T initial, F a_append) : xs(n, -1), data(n, initial), append(a_append) {} bool is_root(int i) { return xs[i] < 0; } int find_root(int i) { return is_root(i) ? i : (xs[i] = find_root(xs[i])); } int set_size(int i) { return - xs[find_root(i)]; } int union_sets(int i, int j) { i = find_root(i); j = find_root(j); if (i != j) { if (set_size(i) < set_size(j)) swap(i,j); xs[i] += xs[j]; xs[j] = i; append(data[i], data[j]); } return i; } bool is_same(int i, int j) { return find_root(i) == find_root(j); } }; int main() { // input int n, m, q; cin >> n >> m >> q; vector<int> a(m), b(m); repeat (j,m) { cin >> a[j] >> b[j]; -- a[j]; -- b[j]; } vector<int> c(q), d(q); repeat (j,q) { cin >> c[j] >> d[j]; -- c[j]; -- d[j]; } // compute disjoint_sets<set<int> > g(n, set<int>(), [&](set<int> & a, set<int> & b) { a.insert(b.begin(), b.end()); b = set<int>(); // free }); repeat (i,n) { g.data[i].insert(i); } set<pair<int,int> > breaking; repeat (j,q) { breaking.emplace(c[j], d[j]); } repeat (j,m) { if (breaking.count(make_pair(a[j], b[j]))) continue; g.union_sets(a[j], b[j]); } const int root = 0; vector<int> ans(n); repeat (i,n) { if (g.is_same(root, i)) { ans[i] = -1; } } repeat_reverse (j,q) { if (g.is_same(c[j], d[j])) continue; set<int> connected; if (g.is_same(root, c[j])) connected.swap(g.data[g.find_root(d[j])]); if (g.is_same(root, d[j])) connected.swap(g.data[g.find_root(c[j])]); g.union_sets(c[j], d[j]); for (int i : connected) { assert (ans[i] == 0); ans[i] = j+1; } } // output assert (ans[root] == -1); repeat_from (i,1,n) { cout << ans[i] << endl; } return 0; }