結果
問題 | No.1326 ふたりのDominator |
ユーザー | chocorusk |
提出日時 | 2020-12-23 00:46:37 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 5,681 bytes |
コンパイル時間 | 1,797 ms |
コンパイル使用メモリ | 145,040 KB |
実行使用メモリ | 30,268 KB |
最終ジャッジ日時 | 2024-09-23 02:59:21 |
合計ジャッジ時間 | 6,468 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | WA | - |
testcase_01 | WA | - |
testcase_02 | WA | - |
testcase_03 | WA | - |
testcase_04 | WA | - |
testcase_05 | WA | - |
testcase_06 | WA | - |
testcase_07 | WA | - |
testcase_08 | WA | - |
testcase_09 | WA | - |
testcase_10 | WA | - |
testcase_11 | WA | - |
testcase_12 | WA | - |
testcase_13 | WA | - |
testcase_14 | WA | - |
testcase_15 | WA | - |
testcase_16 | WA | - |
testcase_17 | WA | - |
testcase_18 | WA | - |
testcase_19 | WA | - |
testcase_20 | WA | - |
testcase_21 | WA | - |
testcase_22 | TLE | - |
testcase_23 | -- | - |
testcase_24 | -- | - |
ソースコード
#include <cstdio> #include <cstring> #include <iostream> #include <string> #include <cmath> #include <bitset> #include <vector> #include <map> #include <set> #include <queue> #include <deque> #include <algorithm> #include <complex> #include <unordered_map> #include <unordered_set> #include <random> #include <cassert> #include <fstream> #include <utility> #include <functional> #include <stack> #define popcount __builtin_popcount using namespace std; typedef long long int ll; typedef pair<int, int> P; using G=vector<vector<int>>; struct LowLink { const G &g; vector< int > used, ord, low; vector< int > articulation; vector< pair< int, int > > bridge; LowLink(const G &g) : g(g) {} int dfs(int idx, int k, int par) { used[idx] = true; ord[idx] = k++; low[idx] = ord[idx]; bool is_articulation = false; int cnt = 0; for(auto &to : g[idx]) { if(!used[to]) { ++cnt; k = dfs(to, k, idx); low[idx] = min(low[idx], low[to]); is_articulation |= ~par && low[to] >= ord[idx]; if(ord[idx] < low[to]) bridge.emplace_back(minmax(idx, (int) to)); } else if(to != par) { low[idx] = min(low[idx], ord[to]); } } is_articulation |= par == -1 && cnt > 1; if(is_articulation) articulation.push_back(idx); return k; } virtual void build() { used.assign(g.size(), 0); ord.assign(g.size(), 0); low.assign(g.size(), 0); int k = 0; for(int i = 0; i < g.size(); i++) { if(!used[i]) k = dfs(i, k, -1); } } }; template< typename G > struct BiConnectedComponents : LowLink { using LL = LowLink; vector< int > used; vector< vector< pair< int, int > > > bc; vector< pair< int, int > > tmp; BiConnectedComponents(const G &g) : LL(g) {} void dfs(int idx, int par) { used[idx] = true; for(auto &to : this->g[idx]) { if(to == par) continue; if(!used[to] || this->ord[to] < this->ord[idx]) { tmp.emplace_back(minmax(idx, to)); } if(!used[to]) { dfs(to, idx); if(this->low[to] >= this->ord[idx]) { bc.emplace_back(); for(;;) { auto e = tmp.back(); bc.back().emplace_back(e); tmp.pop_back(); if(e.first == min(idx, to) && e.second == max(idx, to)) { break; } } } } } } void build() override { LL::build(); used.assign(this->g.size(), 0); for(int i = 0; i < used.size(); i++) { if(!used[i]) dfs(i, -1); } } }; struct DoublingLowestCommonAncestor { const int LOG; vector< int > dep; const G &g; vector< vector< int > > table; DoublingLowestCommonAncestor(const G &g) : g(g), dep(g.size()), LOG(32 - __builtin_clz(g.size())) { table.assign(LOG, vector< int >(g.size(), -1)); } void dfs(int idx, int par, int d) { table[0][idx] = par; dep[idx] = d; for(auto &to : g[idx]) { if(to != par) dfs(to, idx, d + 1); } } void build() { dfs(0, -1, 0); for(int k = 0; k + 1 < LOG; k++) { for(int i = 0; i < table[k].size(); i++) { if(table[k][i] == -1) table[k + 1][i] = -1; else table[k + 1][i] = table[k][table[k][i]]; } } } int query(int u, int v) { if(dep[u] > dep[v]) swap(u, v); for(int i = LOG - 1; i >= 0; i--) { if(((dep[v] - dep[u]) >> i) & 1) v = table[i][v]; } if(u == v) return u; for(int i = LOG - 1; i >= 0; i--) { if(table[i][u] != table[i][v]) { u = table[i][u]; v = table[i][v]; } } return table[0][u]; } }; int main() { int n, m; cin>>n>>m; int u[50050], v[50050]; G g(n); for(int i=0; i<m; i++){ cin>>u[i]>>v[i]; u[i]--; v[i]--; g[u[i]].push_back(v[i]); g[v[i]].push_back(u[i]); } BiConnectedComponents bcc(g); bcc.build(); int b[50050]; fill(b, b+n, -1); int n1=0; for(int x:bcc.articulation){ b[x]=n1++; } n1=bcc.articulation.size()+bcc.bc.size(); vector<vector<int>> g1(n1); for(int i=0; i<bcc.bc.size(); i++){ auto v=bcc.bc[i]; for(auto e:v){ if(b[e.first]!=-1){ int x=b[e.first], y=bcc.articulation.size()+i; g1[x].push_back(y); g1[y].push_back(x); } if(b[e.second]!=-1){ int x=b[e.second], y=bcc.articulation.size()+i; g1[x].push_back(y); g1[y].push_back(x); } } } for(int i=0; i<bcc.bc.size(); i++){ auto v=bcc.bc[i]; for(auto e:v){ if(b[e.first]==-1){ b[e.first]=bcc.articulation.size()+i; } if(b[e.second]==-1){ b[e.second]=bcc.articulation.size()+i; } } } int d[200020]; d[0]=1; auto dfs=[&](auto dfs, int x, int p)->void{ for(auto y:g1[x]){ if(y!=p){ d[y]=d[x]; if(y<bcc.articulation.size()) d[y]++; dfs(dfs, y, x); } } }; dfs(dfs, 0, -1); return 0; DoublingLowestCommonAncestor lca(g1); lca.build(); int q; cin>>q; while(q--){ int x, y; cin>>x>>y; x--; y--; int x1=b[x], y1=b[y]; if(x1==y1){ printf("0\n"); continue; } int p1=lca.query(x1, y1); int ans=d[x1]+d[y1]-2*d[p1]; if(p1<bcc.articulation.size()) ans++; if(x1<bcc.articulation.size()) ans--; if(y1<bcc.articulation.size()) ans--; printf("%d\n", ans); } return 0; }