結果

問題 No.416 旅行会社
ユーザー masamasa
提出日時 2016-08-27 12:39:00
言語 C++14
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 806 ms / 4,000 ms
コード長 2,166 bytes
コンパイル時間 2,640 ms
コンパイル使用メモリ 101,180 KB
実行使用メモリ 27,448 KB
最終ジャッジ日時 2023-08-21 09:52:09
合計ジャッジ時間 10,994 ms
ジャッジサーバーID
(参考情報)
judge13 / judge14
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 333 ms
21,112 KB
testcase_01 AC 2 ms
4,376 KB
testcase_02 AC 2 ms
4,380 KB
testcase_03 AC 2 ms
4,376 KB
testcase_04 AC 1 ms
4,376 KB
testcase_05 AC 2 ms
4,376 KB
testcase_06 AC 2 ms
4,380 KB
testcase_07 AC 3 ms
4,376 KB
testcase_08 AC 9 ms
4,380 KB
testcase_09 AC 41 ms
5,224 KB
testcase_10 AC 360 ms
20,952 KB
testcase_11 AC 365 ms
21,072 KB
testcase_12 AC 366 ms
21,008 KB
testcase_13 AC 341 ms
21,260 KB
testcase_14 AC 779 ms
27,448 KB
testcase_15 AC 785 ms
27,292 KB
testcase_16 AC 806 ms
27,280 KB
testcase_17 AC 804 ms
27,440 KB
testcase_18 AC 779 ms
27,292 KB
testcase_19 AC 616 ms
20,984 KB
testcase_20 AC 613 ms
21,052 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <utility>
#include <set>
#include <map>
#include <list>

using namespace std;

typedef pair<int, int> PII;

class UnionFind {
private:
	// parents[i] >= 0 なら i の親
	// parents[i] < 0 で、根。abs(parents[i])がその木に属する頂点数
	vector<int> parents;
	map<int, list<int>> groups;

public:
	UnionFind();
	UnionFind(int n) {
		parents.assign(n, -1);
		for (int i = 0; i < n; i++) {
			groups[i] = {i};
		}
	}
	~UnionFind() {
		parents.clear();
		groups.clear();
	};

	int find(int x) {
		if (parents[x] < 0) {
			return x;
		} else {
			return parents[x] = find(parents[x]);
		}
	}

	void unite(int x, int y) {
		x = find(x);
		y = find(y);

		if (x == y) {
			return;
		}

		if (size(x) < size(y)) {
			swap(x, y);
		}

		parents[x] += parents[y];
		parents[y] = x;
		groups[x].insert(groups[x].end(), groups[y].begin(), groups[y].end());
		groups.erase(y);
		return ;
	}

	bool same(int x, int y) {
		return find(x) == find(y);
	}

	int size(int x) {
		return -parents[find(x)];
	}

	list<int> getGroup(int x) {
		return groups[x];
	}
};

int main() {
	int n, m, q;

	cin >> n >> m >> q;
	vector<int> a(m), b(m), c(q), d(q);
	for (int i = 0; i < m; i++) {
		cin >> a[i] >> b[i];
		a[i]--;
		b[i]--;
	}

	set<PII> eaten;
	for (int i = 0; i < q; i++) {
		cin >> c[i] >> d[i];
		c[i]--;
		d[i]--;
		eaten.insert(make_pair(c[i], d[i]));
	}

	UnionFind uf(n);
	for (int i = 0; i < m; i++) {
		if (eaten.count(make_pair(a[i], b[i])) == 0) {
			uf.unite(a[i], b[i]);
		}
	}

	vector<int> ans(n, 0);
	for (int i = 0; i < n; i++) {
		if (uf.same(0, i)) {
			ans[i] = -1;
		}
	}

	for (int i = q - 1; i >= 0; i--) {
		bool connects_c = uf.same(0, c[i]);
		bool connects_d = uf.same(0, d[i]);
		if (connects_c == connects_d) {
			uf.unite(c[i], d[i]);
			continue;
		}

		int n_connect = uf.size(0);
		int which = connects_c ? d[i] : c[i];
		auto tmp = uf.getGroup(uf.find(which));
		uf.unite(c[i], d[i]);
		if (uf.size(0) != n_connect) {
			for (auto e : tmp) {
				ans[e] = i + 1;
			}
		}
	}

	for (int i = 1; i < n; i++) {
		cout << ans[i] << endl;
	}
	return 0;
}
0