結果
問題 | No.416 旅行会社 |
ユーザー |
![]() |
提出日時 | 2017-12-29 13:37:53 |
言語 | D (dmd 2.109.1) |
結果 |
AC
|
実行時間 | 466 ms / 4,000 ms |
コード長 | 3,226 bytes |
コンパイル時間 | 734 ms |
コンパイル使用メモリ | 108,800 KB |
実行使用メモリ | 29,056 KB |
最終ジャッジ日時 | 2024-06-12 23:18:13 |
合計ジャッジ時間 | 6,627 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 21 |
ソースコード
import std.algorithm;import std.array;import std.conv;import std.math;import std.range;import std.stdio;import std.string;import std.typecons;int readint() { return readln.chomp.to!int; }int[] readints() { return readln.split.map!(to!int).array; }alias Pair = Tuple!(int, "a", int, "b");void main() {auto nmq = readints;int n = nmq[0], m = nmq[1], q = nmq[2];Pair[] pairs;for (int i = 0; i < m; i++) {auto ab = readints;pairs ~= Pair(ab[0], ab[1]);}bool[Pair] breakMap;Pair[] breaks;for (int i = 0; i < q; i++) {auto cd = readints;auto p = Pair(cd[0], cd[1]);breaks ~= p;breakMap[p] = true;}auto uf = new UnionFind(n);foreach (p; pairs) {// 破壊に関係ない橋if (p !in breakMap) {uf.unite(p.a, p.b);}}auto ans = new int[](n + 1);ans[] = -1; // 全て到達できるforeach_reverse (i, brk; breaks) {// 1 と接続されるかauto a = uf.root(brk.a);auto b = uf.root(brk.b);auto root1 = uf.root(1);if (a != b && (a == root1 || b == root1)) {int nth = cast(int) i + 1;if (a == root1) {// b の集合が 1 と接続されたforeach (x; uf.group(b))ans[x] = nth;}else {// a の集合が 1 と接続されたforeach (x; uf.group(a))ans[x] = nth;}}uf.unite(brk.a, brk.b);}for (int i = 2; i <= n; i++) {if (!uf.isSame(1, i)) {ans[i] = 0; // 最初から到達できない}}for (int i = 2; i <= n; i++)writeln(ans[i]);}class SList {public int node;public SList next;public SList tail;this(int node) {this.node = node;this.next = null;this.tail = this;}/// 引数 list を破壊的に変更するvoid append(SList list) {this.tail.next = list;this.tail = list.tail;}int[] dump() {int[] buf = [node];auto p = this.next;while (p !is null) {buf ~= p.node;p = p.next;}return buf;}}class UnionFind {private int[] _data;private SList[] _groups;this(int n) {_data = new int[](n + 1);_data[] = -1;_groups = new SList[](n + 1);for (int i = 0; i < n + 1; i++)_groups[i] = new SList(i);}int root(int a) {if (_data[a] < 0)return a;return _data[a] = root(_data[a]);}bool unite(int a, int b) {int rootA = root(a);int rootB = root(b);if (rootA == rootB)return false;_data[rootA] += _data[rootB];_data[rootB] = rootA;_groups[rootA].append(_groups[rootB]);return true;}int[] group(int a) {return _groups[root(a)].dump();}bool isSame(int a, int b) {return root(a) == root(b);}int size(int a) {return -_data[root(a)];}}