CF1045C Hyperspace Highways(园方树)
观察到所有成环的之间的距离都是1,因此可以想到使用tarjan缩点后建立园方树
这样答案就是两点间距离/2
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> pll; const int N=1e6+10; int h[N],e[N],ne[N],idx; int dfn[N],ins[N],low[N],w[N],times; int depth[N],fa[N],ans[N][25],fa_e[N]; int vcc[N]; stack<int> st,st_e; vector<int> g[N]; int cnt; int n,m,q; void add(int a,int b){ e[idx]=b,ne[idx]=h[a],h[a]=idx++; } void dfs(int u){ ins[u]=1; dfn[u]=low[u]=++times; int i; st.push(u); for(int i=h[u];i!=-1;i=ne[i]){ int v=e[i]; if(!dfn[v]){ fa[v]=u; dfs(v); low[u]=min(low[u], low[v]); if(dfn[u]<=low[v]){ ++cnt; while(1){ auto x=st.top(); g[cnt].push_back(x); g[x].push_back(cnt); ins[x]=0; st.pop(); if(x == v) break; } g[cnt].push_back(u); g[u].push_back(cnt); } } else if(v!=fa[u]){ low[u]=min(low[u], dfn[v]); } } } int vis[N]; void dfs2(int u){ vis[u]=1; for(int j=1;j<=20;j++){ if(depth[u] <= (1<<j)) break; ans[u][j] = ans[ans[u][j-1]][j-1]; } int v; for(int k=0;k<g[u].size();k++){ v=g[u][k]; if(vis[v]) continue; ans[v][0]=u; depth[v]=depth[u]+1; dfs2(v); } } int lca(int a,int b){ if(depth[a]<depth[b]) swap(a,b); int i; for(i=20;i>=0;i--){ if(depth[ans[a][i]]>=depth[b]){ a=ans[a][i]; } } if(a==b) return a; for(i=20;i>=0;i--){ if(ans[a][i]!=ans[b][i]){ a=ans[a][i]; b=ans[b][i]; } } return ans[a][0]; } int main(){ ios::sync_with_stdio(false); cin>>n>>m>>q; int i; memset(h,-1,sizeof h); for(i=1;i<=m;i++){ int a,b; cin>>a>>b; add(a,b); add(b,a); } cnt=n; dfs(1); depth[1]=1; dfs2(1); while(q--){ int x,y; cin>>x>>y; int p=lca(x,y); cout<<(depth[x]+depth[y])/2-depth[p]<<endl; } return 0; }
没有人不辛苦,只有人不喊疼