結果
問題 |
No.1254 補強への架け橋
|
ユーザー |
![]() |
提出日時 | 2023-12-23 18:06:10 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 72 ms / 2,000 ms |
コード長 | 2,282 bytes |
コンパイル時間 | 1,977 ms |
コンパイル使用メモリ | 209,600 KB |
最終ジャッジ日時 | 2025-02-18 13:53:07 |
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 123 |
ソースコード
#include <bits/stdc++.h> using namespace std; using ll = long long; int main(){ cin.tie(nullptr); ios_base::sync_with_stdio(false); int N, A, B; cin >> N; vector<vector<pair<int, int>>> E(N); for (int i=0; i<N; i++){ cin >> A >> B; A--; B--; E[A].push_back({B, i}); E[B].push_back({A, i}); } vector<int> in(N, -1), low(N), tour, ancestor(N); vector<bool> double_edge(N); auto lowlink=[&](auto self, int from, int p)->void{ in[from] = tour.size(); low[from] = tour.size(); tour.push_back(from); ancestor[from] = p; for (auto [to, _] : E[from]){ if (to == p){ if (double_edge[from]) low[from] = min(low[from], in[to]); else double_edge[from]=1; continue; } if (in[to] != -1){ if (in[to] > in[from]) continue; low[from] = min(low[from], in[to]); //後退辺(子孫->祖先)を遡る } else self(self, to, from); } }; lowlink(lowlink, 0, -1); for (int i=N-1; i>=0; i--){ int x = tour[i]; for (auto [y, _] : E[x]){ if (y == ancestor[x]) continue; low[x] = min(low[x], low[y]); } } //二重辺連結成分分解(two edge connected component) vector<vector<int>> tecc_groups; vector<int> _tecc, bridge, roots={0}; vector<int> tecc_idx(N, -1); //頂点iの含まれる成分の番号 auto tecc=[&](auto self, int from)->void{ _tecc.push_back(from); tecc_idx[from] = tecc_groups.size(); for (auto [to, idx] : E[from]){ if (tecc_idx[to] != -1) continue; if (low[to] > in[from]){ bridge.push_back(idx); roots.push_back(to); } else self(self, to); } }; while(!roots.empty()){ int root = roots.back(); roots.pop_back(); tecc(tecc, root); tecc_groups.push_back(_tecc); _tecc.clear(); } vector<bool> ok(N, 1); for (auto x : bridge) ok[x] = 0; cout << N-bridge.size() << endl; for (int i=0; i<N; i++) if (ok[i]) cout << i+1 << " "; cout << endl; return 0; }