最小生成樹的性質:
(1)最小生成樹並不唯一,準確的來說是最小生成樹的樹形並不唯一
(2)最小生成樹的權值之和唯一,並且是最小的
(3)最小生成樹的邊數 = 頂點數-1
求最小生成樹有兩種經典演算法:普里姆演算法(prim)和克魯斯卡爾(kruskal)演算法
演算法比較:時間複雜度比較
prim在稠密圖中比kruskal優,在稀疏圖中比kruskal劣
prim堆優化效果最好,但是空間花費大,**複雜
krusal這個寫法更簡單寫以及理解一些。
模板:prim(堆優化/優先佇列/向前星):
題目參考:
poj - 1251 jungle roads (prim模板
) poj - 1287 networking (prim)
poj - 2031 building a space station (prim)
zoj - 1586 qs network (kruskal,prim)
fzu - 2254 英語考試 (最小生成樹)
#include #include#include
#include
#include
#include
using
namespace
std;
typedef pair
pii;
const
int maxm =1e5;
const
int inf = 0x3f3f3f3f
;const
int maxn = 30
;int
top;
intn,m;
intans;
inthead[maxn];
intvis[maxn];
intdist[maxn];
//堆過載
struct
cmp};
struct
edgeedge[maxm];
void
init()
void add(int v,int u,int
w)void prim(int
s)
while(!q.empty())}}
}
krusal(並查集):
題目參考:zoj - 1586 qs network (kruskal,prim)
#include#include#include
#include
#include
using
namespace
std;
const
int maxn=1e4;//
點數const
int maxm=1e6+10;//
邊數int
pre[maxn];
intcost[maxn];
struct
edgeedge[maxm];
inttop;
intcnt;
intans;
void addedge(int u,int v,int
w) bool
cmp(edge a,edge b)
int find(int
x)bool unite(int x,int
y)
else
return
false;}
int kruskal(int
n)
if(cnt==n-1) break
; }
if(cnt1) return -1
;
return
ans;
}void init(int
n)
最小生成樹總結
給定一張圖,圖中有許多的節點還有許多長度不同的邊將這些點點相互連線,找出連線所有點的最短方式就是最小生成樹,可以證明,這樣一種最小的情況是不會出現環的,由於所有的無環圖都可以看做樹,所以成為最小生成樹。頂層思想是分治,選擇策略是貪心,實現方法如下 以邊為中心,先將所有的邊從小到大進行排序,之後依照大...
最小生成樹總結
啊,先紀念一下吧,難得一天這麼 666 ac 完了所有題 次小生成樹 看懂 今天學到了最小生成樹演算法中的 prim 演算法和kruskal 演算法。從巨集觀上來講 prim 更適合稠密圖,krustal 更適合稀疏圖,但對於我們來說暫時沒有什麼區別啦。prim 演算法中主要注意的點是 在visit...
最小生成樹總結
研究了一天最小生成樹 衍生出來包括最小瓶頸樹,次小生成樹,最小樹形圖之類的演算法,前兩者基本能搞定,最後那個就。不太懂了日後再回去看吧似乎很少用到,抄個模板以備不時之需 先談談最小瓶頸樹 首先注意這兩個定理 命題 無向圖的最小生成樹一定是瓶頸生成樹。命題 瓶頸生成樹不一定是最小生成樹 好了 知道這個...