這個專題我們討論的問題是在無向圖中尋找一棵最小生成樹(minimum spanning tree)。這個問題對於有向圖的討論也是有意義的,只不過演算法更加複雜,這裡我們將只討論無向圖。最小生成樹存在當且僅當圖是連通的。此處我們不對概念做過多的介紹,直接介紹兩種主要的演算法:
1.kruskal演算法 2.prim演算法(這個演算法留到下一次吧,今晚偷懶,我要陪女朋友去了,哈哈哈!)
kruskal演算法:
第一種演算法本質是一種貪心策略,連續的按照最小權選擇邊,並且當且僅當所選的邊與已取的邊不產生圈時,將該邊加入到最小生成樹的集合裡。形式上,kruskal演算法實際上是在處理乙個森林--樹的集合。開始時存在|v|棵單節點樹(圖g的頂點),而演算法每一步新增一邊在將兩顆樹合併為一棵樹。當演算法終止時,所剩下的樹即為最小生成樹。如我們試圖用kruskal演算法尋找下面圖(graph)g的乙個最小生成樹,圓圈內的為頂點(vertex)的編號,連線代表圖得邊(edge),連線上的數字代表各個邊的權(weight)值。同時,我們將給出該演算法選取邊的步驟。
可能第一次會看不大明白,簡單來說,我們主要的貪心思路是每一步都選取權值最小的邊,且與已選擇的邊不生成圈。講到這,你可以回過頭看看上面的圖,是不是每次都是從最小的權值中選出邊,如果不生成圈,則在集合中加入該邊。
實現的方法有很多,最基本的資料結構要求就是並查集。我們順便在此處給出並查集的模板實現。
#ifndef _disjset_h這是目前最為高效的一種實現方式,雖然看似平平無奇(異常簡單,簡直腦癱),但是困難的是這個資料結構的平均時間的分析,是目前為止從未見過的形式(可能只是我)。所以數學不好的我選擇不給你們分析,m次setunion與find操作的執行時間為o(m logn)。#define _disjset_h
const
int numsets = 1000
;typedef
int disjset[numsets + 1
];typedef
intsettype;
typedef
intelementtype;
void
initialize(disjset s);
void
setunion(disjset s, settype root1, settype root2);
settype find(elementtype x, disjset s);
void
initialize(disjset s)
/*按秩求並
*/void
setunion(disjset s, settype root1, settype root2)
}settype
find(elementtype x, disjset s)
#endif /* disjset */
好的,有了基礎的資料結構,讓我們回到正題,下面我們給出kruskal演算法的偽**:
#ifndef _kruskal_h這裡的選取最小權值的邊是用優先佇列,當然我們也可以預先對邊排個序,依次選取,這個可以依據個人的喜好而定。#define _kruskal_h
void
kruskal(graph g)
}}#endif /*_kruskal_h*/
下面我們看一到簡單的模板題,以及給出ac**,既然是模板題,就不過多講解,初學者對著偽碼和原始碼就可以成功上手kruskal演算法。
/*按秩(高度)求並
*/void
setunion(disjset s, settype root1, settype root2)
}settype
find(elementtype x, disjset s)
#endif /* disjset */#include
#include
#include
using
namespace
std;
struct
edge;
typedef vector
graph;
intcmp(edge a, edge b)
void
kruskal(graph&g)
}printf(
"%d\n
", mstweight);
}int
main()
}kruskal(g);
}return0;
}雖然你們可能會覺得我得**好多不必要的typedef與一些其他的,但是這是我得習慣,看著舒服,哈哈哈~~
最小生成樹專題
首先來回顧一下最小生成樹的概念 在一給定的無向圖 g v,e 中,u,v 代表連線頂點 u 與頂點 v 的邊 即 而 w u,v 代表此邊 的權重,若存在 t 為 e 的子集 即 且為無迴圈圖,使得 的 w t 最小,則此 t 為 g 的最小生成樹。最小生成樹其實是最小權重生成樹的簡稱。簡單地說,就...
最小生成樹專題
一 prim演算法 poj1258 有n個農場,已知這n個農場都互相相通,有一定的距離,現在每個農場需要裝光纖,問怎麼安裝光纖能將所有農場都連通起來,並且要使光纖距離最小,輸出安裝光纖的總距離 資料 幾個點,矩陣表示各點中間的距離 40 4 9 21 4 0 8 17 9 8 0 16 21 17 ...
專題六 最小生成樹 Kuangbin
kuangbin專題 poj1251 jungle roads 最小生成樹 poj1278 networking 最小生成樹 poj2031 building a space station 最小生成樹 poj2421 constructing roads 最小生成樹 zoj1586 qs netw...