最小生成樹(minimum spanning trees),對於乙個連通無向圖g=(v, e)(v為節點集合,e為邊集合), 找g中的乙個無環子集t∈e一些基本的概念:t \in e
t∈e ,使之能夠將所有的節點連線起來,又具有最小的權重,即使得w(t
)=∑(
u,v)
∈tw(
u,v)
w(t) = \sum_ w(u,v)
w(t)=∑
(u,v
)∈t
w(u,
v)的值最小(注:最小生成樹不一定唯一)
舉個栗子:
mst性質:設g = (v, e) 是乙個在邊e上定義了實數值權重函式w的連通無向圖。設集合a為e的乙個子集,且a中包含在圖g的某棵最小生成樹中,設 (s, v - s) 是圖g中尊重集合a的任意乙個切割,又設(u, v)是橫跨切割 (s, v - s)的一條輕量級邊,那麼邊(u, v)對於集合a是安全的。(證明略,可以自行參考演算法導論p364)
根據mst性質,我們就能得到最小生成樹的演算法了
kruskal和prim演算法都是generic-mst演算法的具體實現,二者都是通過乙個具體的規則來確定generic-mst演算法中的第三行所描述的安全邊。兩個演算法的時間複雜度均為o(e演算法描述:lgv)
o(el**)
o(el**
)
集合a始終是乙個森林,開始時,其節點集就是g的節點集,並且a是所有單節點樹構成的森林。之後每次加入到集合a中的安全邊是連線a的兩個不同連通分量的權重最小的邊。
舉個栗子:
詳細**:
kruskal其實主要就是用到並查集,並查集鏈結
#include
#include
using
namespace std;
#define n 5500
#define m 2100
int parent[n]
, depth[n]
;// 並查集模板
void
init
(int n)
}int
find
(int i)
return i;
}inline
bool
connected
(int p,
int q)
void
unionnode
(int p,
int q)
else
if(depth[p]
> depth[q]
)else
if(depth[p]
< depth[q]
)else
}// 查並集模板
struct edge
} arr[m]
;int
main()
sort
(arr +
1, arr + m +1)
;for
(int i =
1; i <= m; i++)if
(num < n -1)
cout <<
"orz"
<< endl;
else
cout << ans << endl;
return0;
}
演算法描述:
舉個栗子:
詳細**實現:
#include
#include
#include
#include
#include
using
namespace std;
#define n 5100
list
int,
int>
> head[n]
;// 記錄以每乙個節點為首的邊的鍊錶
// 例如 head[u] 表示通過u節點的邊的鍊錶, first表示邊的權重, second表示相鄰節點
int vis[n]
;// 記錄每個節點是否被訪問, 0未訪問, 1已訪問
void
prim
(int n)}if
(cnt < n)
cout <<
"orz"
<< endl;
else
cout << ans << endl;
}int
main()
prim
(n);
}
最小生成樹 次小生成樹
一 最小生成樹 說到生成樹首先要解釋一下樹,樹是乙個聯通的無向無環圖,多棵樹的集合則被稱為森林。因此,樹具有許多性質 1.兩點之間的路徑是唯一的。2.邊數等於點數減一。3.連線任意兩點都會生成乙個環。對於乙個無向聯通圖g的子圖,如果它包含g的所有點,則它被稱為g的生成樹,而各邊權和最小的生成樹則被稱...
最小生成樹
package 圖 最小生成樹是用最少的邊吧把所有的節點連線起來。於是和圖的深度優先搜素差不多。class stack public void push int key public int pop 檢視棧頂的元素 public int peek public boolean isempty cla...
最小生成樹
define max vertex num 20 最大頂點數 typedef int adjmatrix max vertex num max vertex num 鄰接矩陣型別 typedef char vertextype typedef struct mgraph struct dnodecl...