社区讨论
54pts tarjan+LCA 求调
P2783有机化学之神偶尔会做作弊参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mhjdj23q
- 此快照首次捕获于
- 2025/11/04 00:48 4 个月前
- 此快照最后确认于
- 2025/11/04 00:48 4 个月前
rt,蒟蒻代码求调。
CPP#include<bits/stdc++.h>
using namespace std ;
const int kMaxN = 1e4 + 5 , kMaxM = 5e4 + 5 ;
struct node
{
int v , nxt ;
}a[kMaxM << 1] ;
struct Edge
{
int u , v ;
}edge[kMaxM << 1] ;
map<pair<int , int> , bool> mp ;
int n , m , q ;
int tim , cnt = 1 , scc ;
int dfn[kMaxN] , low[kMaxN] , head[kMaxN] , color[kMaxN] , dep[kMaxN] , dp[kMaxN][20] ;
bool vis[kMaxN] , fl[kMaxN] ;
stack<int> st ;
vector<int> vans[kMaxN] ;
void add(int u , int v)
{
a[++cnt] = {v , head[u]} ;
head[u] = cnt ;
}
void tarjan(int u , int fa)
{
dfn[u] = low[u] = ++tim ;
vis[u] = 1 ;
st.push(u) ;
for( int i = head[u] ; i ; i = a[i].nxt )
{
int v = a[i].v ;
if(i == fa) continue ;
if(!dfn[v])
{
tarjan(v , i ^ 1) ;
low[u] = min(low[u] , low[v]) ;
}
else if(vis[v])
{
low[u] = min(low[u] , dfn[v]) ;
}
}
if(dfn[u] == low[u])
{
scc++ ;
while(!st.empty())
{
color[st.top()] = scc ;
vis[st.top()] = 0 ;
if(u == st.top())
{
st.pop() ;
break ;
}
st.pop() ;
}
}
}
// void dfs(int u)
// {
// if(dp[u] != -1) return ;
// dp[u] = siz[u] ;
// int maxn = 0 ;
// for( int i = head[u] ; i ; i = a[i].nxt )
// {
// int v = a[i].v ;
// if(dp[v] == -1)
// {
// dfs(v) ;
// }
// maxn = max(maxn , dp[v]) ;
// }
// dp[u] += maxn ;
// }
void write(int x)
{
if(x == 1) cout << 1 ;
else if(x == 0) cout << 0 ;
else
{
write(x >> 1) ;
cout << x % 2 ;
}
}
void dfs(int u , int fa)
{
dep[u] = dep[fa] + 1 ;
dp[u][0] = fa ;
fl[u] = 1 ;
for( int i = 1 ; (1 << i) <= dep[u] ; i++ )
{
dp[u][i] = dp[dp[u][i - 1]][i - 1] ;
}
for( int i = head[u] ; i ; i = a[i].nxt )
{
int v = a[i].v ;
if(fl[v]) continue ;
dfs(v , u) ;
}
}
int lca(int x , int y)
{
if(dep[x] > dep[y]) swap(x , y) ;
for( int i = 20 ; i >= 0 ; i-- )
{
if(dep[dp[y][i]] >= dep[x]) y = dp[y][i] ;
}
if(y == x)
{
return x ;
}
for( int i = 20 ; i >= 0 ; i-- )
{
if(dp[y][i] != dp[x][i]) y = dp[y][i] , x = dp[x][i] ;
}
return dp[x][0] ;
}
void solve()
{
cin >> n >> m ;
for( int i = 1 ; i <= m ; i++ )
{
cin >> edge[i].u >> edge[i].v ;
if(edge[i].u == edge[i].v) continue ;
if(edge[i].u > edge[i].v) swap(edge[i].u , edge[i].v) ;
if(mp[{edge[i].u , edge[i].v}] == 1) continue ;
else mp[{edge[i].u , edge[i].v}] = 1 ;
add(edge[i].u , edge[i].v) ;
add(edge[i].v , edge[i].u) ;
}
for( int i = 1 ; i <= n ; i++ )
{
if(!dfn[i])
{
tarjan(i , 0) ;
}
}
cnt = 1 ;
memset(head , 0 , sizeof head) ;
mp.clear() ;
for( int i = 1 ; i <= m ; i++ )
{
if(color[edge[i].u] != color[edge[i].v])
{
int cu = color[edge[i].u] , cv = color[edge[i].v] ;
if(cu > cv) swap(cu , cv) ;
if(mp[{cu , cv}] == 1) continue ;
else mp[{cu , cv}] = 1 ;
add(color[edge[i].u] , color[edge[i].v]) ;
add(color[edge[i].v] , color[edge[i].u]) ;
}
}
for( int i = 1 ; i <= n ; i++ )
{
if(!fl[i]) dfs(i , 0) ;
}
cin >> q ;
while(q--)
{
int x , y ;
cin >> x >> y ;
int z = lca(color[x] , color[y]) ;
// cout << dep[z] << " " ;
write((dep[color[x]] + dep[color[y]]) - (dep[z] * 2) + 1) ;
cout << "\n" ;
}
// write(0) ;
// cnt = 1 ;
// memset(head , 0 , sizeof head) ;
// for( int i = 1 ; i <= m ; i++ )
// {
// if(color[edge[i].u] != color[edge[i].v])
// {
// add(color[edge[i].u] , color[edge[i].v]) ;
// }
// }
// memset(dp , -1 , sizeof dp) ;
// int maxn = 0 ;
// for( int i = 1 ; i <= scc ; i++ )
// {
// if(dp[i] == -1) dfs(i) ;
// maxn = max(maxn , dp[i]) ;
// }
// cout << maxn ;
// memset(dp , -0x3f , sizeof dp) ;
// dp[0] = 0 ;
// for( int i = 1 ; i <= scc ; i++ )
// {
// for( int j = w ; j >= sizc[i] ; j-- )
// {
// dp[j] = max(dp[j] , dp[j - sizc[i]] + sizd[i]) ;
// }
// }
// cout << dp[w] ;
}
int main()
{
int t = 1 ;
// cin >> t ;
while(t--) solve() ;
return 0 ;
}
回复
共 0 条回复,欢迎继续交流。
正在加载回复...