學習筆記 虛樹

2022-04-29 23:39:10 字數 3160 閱讀 9737

模板:(樹剖\(lca\)+建虛樹)

#include using namespace std;

const int maxn=100000+10;

int n,m,dp[maxn],vis[maxn],h[maxn],sta[maxn],top;

int fir[maxn],head[maxn],to[maxn<<1],nxt[maxn<<1],tot,cnt;

int top[maxn],dep[maxn],id[maxn],siz[maxn],son[maxn],fa[maxn],tim;

struct nodee[maxn<<1];

inline int read()

while(isdigit(ch))

return (f==1)?x:-x;

}inline void add(int x,int y)

inline void addedge(int x,int y)

void dfs1(int x,int f)

bool cmp(int a,int b)val_)\),其中 \(val\) 為邊權。

\(code\ below:\)

#include #define int long long

using namespace std;

const int maxn=250000+10;

const int inf=1e18;

int n,m,dp[maxn],dis[maxn],vis[maxn],h[maxn],sta[maxn],top;

int fir[maxn],head[maxn],to[maxn<<1],nxt[maxn<<1],tot,cnt;

int top[maxn],dep[maxn],id[maxn],siz[maxn],son[maxn],fa[maxn],tim;

struct nodee[maxn<<1];

inline int read()

while(isdigit(ch))

return (f==1)?x:-x;

}inline void add(int x,int y,int w)

inline void addedge(int x,int y)

void dfs1(int x,int f)

bool cmp(int a,int b)

ans-=2*now*dep[x];

if(vis[x]) ans-=2*sub[x]*dep[x],sub[x]++;

}

找最小邊權就是記錄一下最小值和次小值,然後更新 \(ans\)

找最大邊權同個道理

int dfs_min(int x)

if(vis[x]&&min!=inf) ans=min(ans,min-dep[x]);

if(min!=inf&&sec!=inf) ans=min(ans,min+sec-2*dep[x]);

if(vis[x]) min=dep[x];

return min;

}int dfs_max(int x)e[maxn<<1];

inline int read()

while(isdigit(ch))

return (f==1)?x:-x;

}inline void add(int x,int y)

inline void addedge(int x,int y)

void dfs1(int x,int f)

bool cmp(int a,int b)

if(vis[x]&&min!=inf) ans=min(ans,min-dep[x]);

if(min!=inf&&sec!=inf) ans=min(ans,min+sec-2*dep[x]);

if(vis[x]) min=dep[x];

return min;

}int dfs_max(int x) dp[son]\)

2、\(vis[x]=0,sum>1\),那就直接選 \(x\),\(x\) 的子樹已經被 \(x\) 封死了

3、\(vis[x]=0,sum\leq 1\),那就傳到 \(x\) 的父親上,讓 \(x\) 的父親解決好了

\(code\ below:\)

#include using namespace std;

const int maxn=100000+10;

int n,m,dp[maxn],vis[maxn],h[maxn],sta[maxn],top;

int fir[maxn],head[maxn],to[maxn<<1],nxt[maxn<<1],tot,cnt;

int top[maxn],dep[maxn],id[maxn],siz[maxn],son[maxn],fa[maxn],tim;

struct nodee[maxn<<1];

inline int read()

while(isdigit(ch))

return (f==1)?x:-x;

}inline void add(int x,int y)

inline void addedge(int x,int y)

void dfs1(int x,int f)

bool cmp(int a,int b)

int main()

dfs1(1,0);dfs2(1,1);

m=read();

for(int t=1;t<=m;t++)

flag=0;

for(int i=1;i<=k;i++)

flag|=vis[fa[h[i]]];

if(flag)

sort(h+1,h+k+1,cmp);

cnt=0;sta[top=1]=1;

for(int i=1;i<=k;i++)

addedge(sta[top-1],sta[top]);

top--;

}if(sta[top]!=h[i]) sta[++top]=h[i];

} while(--top) addedge(sta[top],sta[top+1]);

printf("%d\n",dfs(1));

for(int i=1;i<=k;i++) vis[h[i]]=0;

}return 0;

}

虛樹學習筆記

將關鍵點按dfs序排序後,所有關鍵點與相鄰關鍵點的lca合起來構成虛樹 通常還要加上整棵樹的根 虛樹至多有2k2k 個點。體現在實現中就是每次都pop若干點,並有機會push2個點。stk中存的是從根到當前點的遞迴棧中目前選入虛樹的點。stk中的點之間都未連邊 因為事實上關係還未確定 pop掉乙個點...

虛樹 學習筆記

水平不夠,學習來湊 又開了個天大的新坑 sdoi 2011 消耗戰 題目大意就是講 給出一棵樹,有邊權,然後給出k個查詢點,問從1號店不能到任何乙個查詢點的代價是多少.先考慮一下樹形動歸.dp i 表示從1不能到以i為根的子樹中的所有查詢點的最小代價 考慮維護乙個量,mins i 表示從1到i路徑最...

虛樹學習筆記

虛樹常常被使用在樹形 dp 中。有些時候,我們需要計算的節點僅僅是一棵樹中的某幾個節點 這個時候如果對整棵樹都進行一次計算開銷太大了 所以我們需要把這些節點從原樹中抽象出來 按照它們在原樹中的關係重新建一棵樹,這樣的樹就是虛樹 在構建之前,我們需要把所有需要加入的節點按照 dfn 序從小到大排好序 ...