結果
問題 | No.1326 ふたりのDominator |
ユーザー | chocorusk |
提出日時 | 2020-12-23 00:36:54 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 5,719 bytes |
コンパイル時間 | 1,625 ms |
コンパイル使用メモリ | 144,656 KB |
実行使用メモリ | 22,804 KB |
最終ジャッジ日時 | 2024-09-23 02:58:54 |
合計ジャッジ時間 | 3,740 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
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 | WA | - |
testcase_23 | WA | - |
testcase_24 | WA | - |
ソースコード
#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 LCA{ vector<vector<int>> g; vector<int> d; vector<vector<int>> p; int log; int n; LCA(const vector<vector<int>> &g):n(g.size()), g(g), d(g.size()){ log=0; while(1<<log<=n) log++; p.resize(log, vector<int>(n)); } void dfs(int x, int prev){ for(auto y:g[x]){ if(y==prev) continue; d[y]=d[x]+1; p[0][y]=x; dfs(y, x); } } void build(){ dfs(0, -1); for(int i=1; i<log; i++){ for(int j=0; j<n; j++){ p[i][j]=p[i-1][p[i-1][j]]; } } } int lca(int a, int b){ if(d[a]>d[b]) swap(a, b); int dd=d[b]-d[a], i=0; int a1=a, b1=b; while(dd){ if(dd&1) b1=p[i][b1]; dd>>=1; i++; } if(a1==b1) return a1; for(int j=log-1; j>=0; j--){ if(p[j][a1]!=p[j][b1]){ a1=p[j][a1], b1=p[j][b1]; } } return p[0][a1]; } int dist(int a, int b){ return d[a]+d[b]-2*d[lca(a, b)]; } }; 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; } } } return 0; LCA lca(g1); lca.build(); 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); 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.lca(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; }