statement 基環樹 虛樹 倍增

2021-08-28 11:39:26 字數 3298 閱讀 8692

這個題寫的真爽翻了。

題目大意就是給你乙個樹和基環樹森林(內向),邊有權,每次詢問給你兩個點集,問所有黑點到白點的路徑中,邊權最大值最小是多少。

題解:首先考慮樹,直接建出虛樹來跑一遍dfs即可。然後每個環會選出一些點來,那些點先計算出乙個貢獻,你只要把環倍長然後那些點排個序,在上面做倍增即可。

#include

#include

#include

#include

#include

#include

#define gc getchar()

#define n 200010

#define log 22

#define inf (int_max/100)

#define pb push_back

#define debug(x) cerr<<#x<<"="<#define sp <<" "

#define ln int zx[n]

,in[n]

,up[n]

[log]

,mxv[n]

[log]

,rup[n]

[log]

,rmx[n]

[log]

,d[n]

,ccnt,dfc,vis[n]

;int val[n]

,xs[n]

,gx[n]

,s[n]

,stcl[n]

,ct[n]

,csz[n]

,p[n]

,wp[n]

,lst[n]

,bc[n]

,log[n]

;vector<

int> g[n]

,cyc[n]

,a[n]

;struct edgese[n]

;int h[n]

,etop;

inline

intadd_edge

(int u,

int v,

int w)

inline

intinn()

inline

intincmp

(int x,

int y)

inline

intctcmp

(int x,

int y)

intdfs

(int x,

int z)

inline

intgetlca

(int x,

int y)

inline

intgetmx

(int x,

int y)

intdfs_virtual

(int x,

int rt)

for(

int i=

0,y;i<

(int

)g[x]

.size()

;i++

) xs[y=g[x]

[i]]

=xs[x]

,ans=

min(ans,

dfs_virtual

(y,rt));

return ans;

}inline

intgetans

(vector<

int>

&a,int rt)

while

(t>

1) g[s[t-1]

].pb(s[t]

),stcl[

++sl]

=s[t]

,t--

; xs[rt]=0

;int ans=

dfs_virtual

(rt,rt)

;for

(int i=

1;i<=sl;i++

) g[stcl[i]].

clear()

;return ans;

}inline

intquery

(int x,

int y)

inline

intsolve

(vector<

int> c)

return ans;

}int

main()

for(

int i=

1;i<=n;i++)if

(ct[i]

) rup[i][0

]=p[i]

,rmx[i][0

]=wp[i]

;for

(int i=

1;i)for

(int x=

1;x<=n;x++)if

(ct[x]

) rup[x]

[i]=rup[rup[x]

[i-1]]

[i-1],

rmx[x]

[i]=

max(rmx[x]

[i-1

],rmx[rup[x]

[i-1]]

[i-1])

;for

(int i=

1;i<=n;i++)if

(!ct[i]

)add_edge

(p[i]

,i,wp[i]);

for(

int i=

1;i<=n;i++)if

(ct[i]

) dfc=

0,d[i]=1

,dfs

(i,i)

;/*for(int i=1;i<=n;i++) if(ct[i])

for(int i=1;i<=n;i++) if(!ct[i])

*/for

(int q=

inn(

);q;q--

)for

(int i=

1,x;i<=tc+fc;i++)if

(cyc[x=bc[zx[lst[i]]]

].size()

) ans=

min(ans,

solve

(cyc[x]))

,cyc[x]

.clear()

;for

(int i=

1;i<=tc+fc;i++

) val[lst[i]]=

0;if(ans<=m)

printf

("%d\n"

,ans)

;else

printf

("ok\n");

}return0;

}

初識基環樹 gay環樹?

衢州飯店出鍋了?以為自己幸運,哪知無法逃過一劫。學個oi,菊花不保啊 霧。最近考了好多道關於基環樹 包括基環內向樹基環 外向樹 的題,趁機學一波 首先明確,基環樹不是樹。其是一顆樹 一條額外的邊,即一顆樹 乙個環。大致簡述一下這種特殊結構出現的主要原因就是n個點連出去n條邊,而樹是n點n 1條邊,這...

基環樹小結

持續更新ing 圖 的環顯而易見,一般的初始化流程有兩個 1 找環 void get ring ll u,ll fa cf835f 題目大意 刪掉一條邊,在保持聯通性的基礎上求最小直徑 既然要保持連通性,就只能考慮在環上刪邊 先將環中的每個節點子樹最大直徑求出 不跨過環 ll get d ll u,...

基環樹略解

基環樹,也叫環套樹,是一種圖的型別。如果連通圖 g g g 有 v e v e v e 則我們稱它是基環樹。顧名思義,基環樹就好似是在一棵樹上加一條邊得到的圖。基環樹有且僅有乙個環,所以也被成為環套樹。如上圖所示的圖就是一棵基環樹。基環樹沒什麼用。它只能解決部分特殊問題,而這類問題通常會註明 邊數 ...