kruscal重構樹略解

2022-04-30 13:21:10 字數 2461 閱讀 5042

這道題珂以用啟發式合併+主席樹來做

離線做法就不行了

我們就要用乙個叫做kruscal重構樹的東西來解決這個問題

克魯斯卡爾重構樹可以用來解決一類諸如「查詢從某個點出發經過邊權不超過val的邊所能到達的節點」的問題

首先不難發現,上面這個問題肯定是在最小生成樹上走最優,其他邊都可以不用去管

kruscal構樹的思想就是在建最小生成樹的時候不是直接連邊,而是新建乙個節點,並把這個節點的值設為邊權,然後令兩個連通塊的代表點分別作為它的左右兒子。然後令這個新節點成為整個連通塊的代表點

那麼這樣做有什麼用呢?

kruscal重構樹有這樣的性質:乙個點的所有子樹節點的權值都小於等於它的權值,並且從它開始逐漸向子節點移動,權值是單調不上公升的。這個性質是顯然的,因為我們在構造樹的時候是從小到大插入的邊,因此父親節點的權值一定大於等於子節點的值

查詢時,首先可以在樹上倍增得到當前查詢點所能夠到達的最遠的祖先點,那麼從這個點能夠到達的符合邊權限制條件的連通塊中的節點,就是祖先點的子樹中所有的葉節點

然後我們按dfs序維護乙個主席樹上樹就可以解決了

完整**(離線)

#include #define getchar nc

#define n 200005

#define m n<<4

#define k 500005

using namespace std;

inline char nc()

inline int read()

while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();

return x*f;

}inline void write(register int x)

struct node

node(int u,int v,int c):u(u),v(v),c(c){}

inline bool operator <(const node &b)const

inline void update(register int last,register int &now,register int l,register int r,register int x)

inline int query(register int a,register int x,register int k)

return b[r];

}inline void dfs(register int u)

inline int find(register int x)

int main()

sort(e+1,e+m+1);

dfn=n;

for(register int i=1;i<=m;++i)

}for(register int i=1;i<=dfn;++i)

if(!ls[i])

dfs(find(i));

while(q--)

return 0;

}

#include #define getchar nc

#define n 200005

#define m n<<4

#define k 500005

using namespace std;

inline char nc()

inline int read()

while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();

return x*f;

}inline void write(register int x)

struct node

node(int u,int v,int c):u(u),v(v),c(c){}

inline bool operator <(const node &b)const

inline void update(register int last,register int &now,register int l,register int r,register int x)

inline int query(register int a,register int x,register int k)

return b[r];

}inline void dfs(register int u)

inline int find(register int x)

int main()

sort(e+1,e+m+1);

dfn=n;

for(register int i=1;i<=m;++i)

}for(register int i=1;i<=dfn;++i)

if(!ls[i])

dfs(find(i));

int lastans=0,v,x,k;

while(q--)

return 0;

}

學習筆記 Kruscal 重構樹

網上感覺沒有什麼很詳細 證明的講解啊 前置 kruskal 求最小生成樹。這個演算法可以將一棵樹 無向連通圖重構成一顆有性質的新樹。演算法可以解決一些樹上瓶頸邊權之類的問題,可以把需要持久化的並查集給代替掉。設 f i 為 i 所在聯通塊的根。演算法流程和 kruskal 最小生成樹的過程非常類似 ...

基環樹略解

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

B樹 B 樹 B 樹 B 樹略解

b 樹 即二叉搜尋樹 1.所有非葉子結點至多擁有兩個兒子 left 和right 2.所有結點儲存乙個關鍵字 3.非葉子結點的左指標指向小於其關鍵字的子樹,右指標指向大於其關鍵字的子樹 如 b樹的搜尋,從根結點開始,如果查詢的關鍵字與結點的關鍵字相等,那麼就命中 否則,如果查詢關鍵字比結點關鍵字小,...