結果
問題 | No.416 旅行会社 |
ユーザー |
![]() |
提出日時 | 2023-02-15 23:44:13 |
言語 | C++17(gcc12) (gcc 12.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 374 ms / 4,000 ms |
コード長 | 3,931 bytes |
コンパイル時間 | 8,634 ms |
コンパイル使用メモリ | 211,532 KB |
最終ジャッジ日時 | 2025-02-10 15:46:17 |
ジャッジサーバーID (参考情報) |
judge1 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 21 |
ソースコード
#pragma GCC target("avx2")#pragma GCC optimize("unroll-loops")#include <algorithm>#include <bitset>#include <climits>#include <cmath>#include <cstring>#include <deque>#include <forward_list>#include <functional>#include <iomanip>#include <iostream>#include <list>#include <map>#include <numeric>#include <queue>#include <random>#include <regex>#include <set>#include <stack>#include <string>#include <unordered_map>#include <unordered_set>#include <utility>#include <vector>#define ALL(x) (x).begin(), (x).end()#define PC(x) __builtin_popcount(x)#define PCL(x) __builtin_popcountll(x)using namespace std;typedef long long ll;typedef unsigned long long ull;typedef pair<int, int> pii;typedef pair<ll, ll> pll;template <class T>bool chmax(T& a, const T& b){if (a < b) {a = b;return true;}return false;}template <class T>bool chmin(T& a, const T& b){if (b < a) {a = b;return true;}return false;}const double PI = 3.14159265358979323846;const double PI2 = PI * 2.0;const double EPS = 1E-09;const ll MOD = 1E+09 + 7; // =998244353;const ll INFL = 1E18;const int INFI = 1E09;const int MAX_N = 2E+05;struct edge {int to, cost, id;};ll di[4] = { 0, -1, 0, 1 }, dj[4] = { 1, 0, -1, 0 };struct unionfind {vector<int> par, t_rank, siz;vector<vector<int>> group;unionfind(int n) // n要素で初期化(1-indexed): par(n + 1), t_rank(n + 1), siz(n + 1), group(n + 1){// n要素で初期化// 1-indexedになっているので0-indexedで使いたいときは注意for (int i = 0; i <= n; i++) {par[i] = i;siz[i] = 1;t_rank[i] = 0;group[i].push_back(i);}}// 木の根を求めるint find(int x){if (par[x] == x) {return x;} else {return par[x] = find(par[x]);}}// xとyの属する集合を併合void unite(int x, int y){x = find(x);y = find(y);if (x == y)return;if (siz[x] < siz[y]) {par[x] = y;siz[y] += siz[x];for (int i : group[x]) {group[y].emplace_back(i);}} else {par[y] = x;siz[x] += siz[y];if (t_rank[x] == t_rank[y])t_rank[x]++;for (int i : group[y]) {group[x].emplace_back(i);}}}// xとyが同じ集合に属するか否かbool same(int x, int y){return find(x) == find(y);}// xの属するグループのサイズを求めるint size(int x){return siz[find(x)];}};int N, M, Q;int C[MAX_N + 1], D[MAX_N + 1], ans[MAX_N + 1];int main(){ios::sync_with_stdio(false);cin.tie(nullptr);cin >> N >> M >> Q;set<pii> st;for (int i = 1; i <= M; ++i) {int a, b;cin >> a >> b;st.insert({ a, b });}for (int i = 1; i <= Q; ++i) {cin >> C[i] >> D[i];st.erase({ C[i], D[i] });}fill(ans + 1, ans + N + 1, 0);unionfind uft(N);for (const auto& [u, v] : st) {uft.unite(u, v);}for (int i : uft.group[uft.find(1)]) {ans[i] = -1;}for (int i = Q; i >= 1; --i) {int c = C[i], d = D[i];if (!uft.same(c, d)) {int v = 0;if (uft.same(c, 1))v = d;else if (uft.same(d, 1))v = c;if (v != 0) {for (int j : uft.group[uft.find(v)]) {ans[j] = i;}}}uft.unite(c, d);}for (int i = 2; i <= N; ++i) {cout << ans[i] << "\n";}return 0;}