次小生成樹

2022-05-01 13:27:09 字數 2760 閱讀 8441

次小生成樹的定義:

次小生成樹根據名字就知道是比最小生成樹的權值和還要大的生成樹,而且是大於最小生成樹的權值和的權值最小的那個生成樹。

次小生成樹的求法:

1.暴力拆邊法

由最小生成樹可得最小生成樹中的邊的權值和最小,那麼我們可以每次考慮列舉刪除其中的邊,並用其他的權值盡量小的非樹邊頂上,對新的生成樹的權值和取個min就行了,時間複雜度:o(nmlogm)。

#10068. 「一本通 3.1 練習 3」秘密的牛奶運輸:

#includeusing

namespace

std;

#define re register int

#define ll long long

#define inf 0x3f3f3f3f

#define maxn 509

#define maxm 10009inline ll read()

while(ch>='

0'&&ch<='9')

return x*f;

}struct

edge

p[maxm];

intn,m,k,tot,cnt;

intfa[maxn],vis[maxn];

ll ans,mx,sum;

bool

comp(edge a,edge b)

int find(int

x)int

main()

}mx=1e18;

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

}if(sum>ans)

mx=min(mx,sum);

}if(mx==1e18)

mx=10

; printf(

"%lld\n

",mx);

fclose(stdin);

fclose(stdout);

return0;

}

2.倍增

考慮在最小生成樹中加一條非樹邊(u,v),那麼整棵樹將會形成乙個環,去掉環上的任意一條邊後仍然為一顆生成樹,因為我們所需要求的是次小生成樹,所以可以貪心地將環上樹邊中權值最大的邊刪除並加上邊(u,v)。

實現:①先用kruskal求出最小生成樹並標記樹邊和最小生成樹的權值和。

②用dfs求出f陣列和每個節點的深度。

③用倍增的方法求出最小生成樹中任意兩點間路徑的最大和次大值。

④列舉每一條非樹邊(u,v),利用lca求出環上的樹邊的最大值,將其權值減去並加上樹邊(u,v)的權值,更新答案。

求次大值是因為所求為嚴格的次小生成樹,其權值和要大於最小生成樹的權值和,當所列舉的非樹邊的邊權和環上樹邊的最大值相同時便取次大值。

因為取最大值後所形成的心得生成樹的權值和與原來的最小生成樹的權值和必然相等,並不滿足題目要求。

bzoj 1977 次小生成樹 tree:

#includeusing

namespace

std;

#define re register int

#define ll long long

#define inf 0x3f3f3f3f

#define maxn 100009

#define maxm 300009inline ll read()

while(ch>='

0'&&ch<='9')

return x*f;

}struct

edge

pp[maxm];

struct

edge

p[maxn

<<1

];bool

used[maxm];

int head[maxn],depth[maxn],f[maxn][29

],fa[maxn];

ll mx[maxn][

29],cmx[maxn][29

];int

n,m,k,tot,cnt;

ll ans,sum;

//f[i][j]表示節點i往父節點方向走2^j步後的節點編號

//mx[i][j] ... 間的路徑上邊的最大值

//cmx[i][j] ... 次大值

void add(int x,int

y,ll z)

bool

comp(edge a,edge b)

int find(int

x)void kruskal()//

求最小生成樹

}}void dfs(int u,int father)//

求f陣列和depth陣列 每個點的深度

}void cal()//

倍增求出mx和cmx

}int lca(int x,int

y)ll query_mx(

int x,int y,int lca,ll val)//

倍增找(u,v)路徑上的最大值,分為u->lca 和 v->lca

for(int i=20;i>=0;i--)

if(depth[lca]<=depth[y]-(1

max(lmx,rmx);

}void get_ans()//

列舉非樹邊

printf(

"%lld\n

",sum);

}int

main()

最小生成樹 次小生成樹

一 最小生成樹 說到生成樹首先要解釋一下樹,樹是乙個聯通的無向無環圖,多棵樹的集合則被稱為森林。因此,樹具有許多性質 1.兩點之間的路徑是唯一的。2.邊數等於點數減一。3.連線任意兩點都會生成乙個環。對於乙個無向聯通圖g的子圖,如果它包含g的所有點,則它被稱為g的生成樹,而各邊權和最小的生成樹則被稱...

次小生成樹

演算法引入 設g v,e,w 是連通的無向圖,t是圖g的一棵最小生成樹 如果有另一棵樹t1,滿足不存在樹t t t1 則稱t1是圖g的次小生成樹 演算法思想 鄰集的概念 由t進行一次可行交換得到的新的生成樹所組成的集合,稱為樹t的鄰集,記為n t 設t是圖g的最小生成樹,如果t1滿足 t1 min,...

次小生成樹

分類 圖論 2013 02 12 15 03 32人閱讀收藏 舉報次小生成樹 在求最小生成樹時,用陣列path i j 來表示mst中i到j最大邊權。求完後,直接列舉所有不在mst中的邊,把它加入到mst中構成一棵新的樹,且該樹有環,此環是由剛加入的邊 i,j 造成的,所以可以通過刪除path i ...