完美生成樹 題解

2021-08-21 06:06:09 字數 1828 閱讀 3809

題目大意:

在乙個「無向有色圖」中求一棵最小生成樹,且要求樹邊必須包含至少兩種顏色。 1≤

n點數,

e邊數≤

100000,1

≤col

or顏色

,w邊數

≤1000000000

1 ≤n

點數,e

邊數

≤100000,1

≤col

or顏色

,w邊數

≤1000000000

第一眼看到資料範圍簡直令人絕望

不過,據大佬說這題只是noip普及組難度!!!關鍵是考試時居然寫炸了!!!

但實際上很多時候這些巨大數值並無關緊要:hash,離散等,只要麻煩點預處理一下就ok了

當然,對於這題是不需要的

思考一下,顯然先求他一趟最小生成樹——

若此時顏色已經滿足,那最好,直接出了答案

但若不滿足呢?顯然也是在這棵最小生成樹上做一些變動來得到答案

那麼關鍵就是如何變動

——事實上,有且僅有一條原樹邊會被替換掉:

首先,顯然,替換了一條樹邊後樹邊的總權值變大了(不然原來的就不叫最小生成樹了)

那麼假如我們再替換一條邊,樹邊的總權值還會變大

所以說,有且僅有一條原樹邊會被替換掉

然後,這不就是變形的次小生成樹嗎?

加入一條邊後,在這條邊所形成的環中找一條最大的樹邊替換掉

快速找樹上最大邊——lca另開個p陣列記一下權值不就ok了嗎?

於是:

kruskal+建最小生成樹

lca+預處理p陣列

列舉一條顏色不同的邊「假裝」加入,求此時次小生成樹

#include

#include

#define ll long long

#define max(x,y) max(x,y)

#define min(x,y) (x)<(y)?(x):(y)

using

namespace

std;

const

int maxn=(1e5)+5,log=21;

int n,m,col=-1,fa[maxn];bool vis[maxn],***=0;ll ans,val=((ll)1

<<60);

int getfa(int x)

int tot,son[maxn<<1],nxt[maxn<<1],lnk[maxn],w[maxn<<1];

void add_e(int x,int y,int z)

int dep[maxn],up[maxn][log],p[maxn][log],pow[maxn];

void dfs(int x,int da,int va)

int lca(int x,int y)

struct ff

}char gt()

int read()

int main();

work();

if(***)

dfs(1,0,0);

for(int i=1;i<=n;i++) pow[i]=pow[i-1]+((1

printf("%lld\n",val);

return

0;}

題解 SHOI2010 最小生成樹

題目大意 在乙個合法的連通圖中,每條邊都有乙個邊權,我們欽定一條邊。然後對圖進行一些操作 將某一條邊的權值 1或 1。請問至少多少次後可以使欽定的邊出現在該圖的最小生成樹中。luogu傳送門 shoi2010 最小生成樹 解題思路 說實話 我們一定要跳出題目的侷限性,畢竟網路流是屬於圖演算法。我們考...

貨車運輸題解 最大生成樹 lca

2013年noip全國聯賽提高組 時間限制 1 s 空間限制 128000 kb a 國有 n 座城市,編號從 1 到 n,城市之間有 m 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。現在有 q 輛貨車在運輸貨物,司機們想知道每輛車在不超過車輛限重的情況下,最多能運多重的貨物。輸入描述 in...

BZOJ1016 最小生成樹計數 題解

顯然的是,不同的生成樹的不同權值的邊數一定是一樣的 我們可以先跑一遍kruskal把每種邊需要多少條記錄一下 然後由於相同權值的邊不超過10條,所以在相同權值的邊內部搜一下,看哪些邊加進原圖無環 然後乘法原理和前面的答案乘一下 不同的選擇方法對後面的並查集的更新肯定是沒有影響的,不然一開始的krus...