鏈式前向星-學習筆記
一、prim演算法
普通prim演算法模板:
//堆優化的prim演算法:用前向星錄資料的時候記得把head初始化為-1
fill(dist,dist+len,max);
memset(vis,
0,sizeof
vis);
int ans=0
;dist[
1]=0; //
如果題目要求輸出最小生成樹,就把題目要求的源點s的dist設為0
while(1)
}if(u<0) break; //
如果題目要求判斷最小生成樹是否能覆蓋所有邊,出現這樣的情況說明不能覆蓋所有邊。
vis[u]=1
; ans+=dist[u];
for(i=head[u];~i;i=mp[i].next)
}}o(
"%d\n
",ans);
堆結構:
struct演算法**:cmp};
priority_queue
,cmp> pq;
int ans=0二、kruskal演算法;dist[
1]=0
;pq.push(1);
while(!pq.empty())
}}o(
"%d\n
",ans);
1.建立邊表資料結構
typedef struct2.編寫並查集模板(以下**沒有寫合併的union操作。這個操作在主**執行的時候已經實現)edge
bool
operator
< (const edge& obj) const
}edge;
edge mp[len*len];
int3.編寫主**fa[len];
intinit()
int findfa(int
x)
int t=x;
while(x!=fa[x])
return
r;}
sort(mp,mp+cnt);注意:①邊表的範圍要開大,因為邊的數目可能是頂點數目的平方(準確說,有向圖邊樹e=n*(n-1) )ff(i,cnt)}o(
"%d\n
",ans);
②prim演算法在錄邊的資料的時候,因為是無向圖,一條邊要錄成兩條。kruskal就沒有這種必要了。
③各種初始化**(比如並查集的init() )要注意加上。
打個oj測試一下吧!
ac**:
#include #includeview code#include
#include
#include
#include
#include
#include
#include
#include
#define i scanf
#define ol puts
#define o printf
#define f(a,b,c) for(a=b;a#define ff(a,b) for(a=0;a#define fg(a,b) for(a=b-1;a>=0;a--)
#define len 1010
#define max (1<<30)-1
#define v vectorusing
namespace
std;
intn;
intfa[len];
intinit()
int findfa(int
x)
int t=x;
while(x!=fa[x])
returnr;}
typedef
struct
edge
bool
operator
< (const edge& obj) const
}edge;
edge mp[len*len];
int cnt=0
;int
main()
sort(mp,mp+cnt);
ff(i,cnt)}o(
"%d\n
",ans);
}return0;
}
最小生成樹詳解
對於無向圖g v,e v 表示圖中的結點,e表示圖中的邊,所謂最小生成樹就是聯通圖 g中所有結點所需要的邊長度總和最小,這些邊加上 v就構成圖 g的一顆最小生成樹。這樣還不清楚我們可以舉個例子 有 n個城市分布在不同的地方,為了保證每個城市間都能用火車通行,我們需要在城市之間修鐵路,但是為了節約成本...
最小生成樹(詳解)
最小生成樹和最短路還是區別很大的,所以又雙叒來寫了。最小生成樹問題顧名思義,概括來說就是路修的最短。接下來引入幾個一看就明白的定義 帶權圖 邊賦以權值的圖稱為網或帶權圖,帶權圖的生成樹也是帶權的,生成樹t各邊的權值總和稱為該樹的權。最小生成樹 mst 權值最小的生成樹。最小生成樹的性質 假設g v,...
Prim演算法生成最小生成樹詳解
建立乙個low陣列代表相應每個節點連線所需最小費用,乙個vis陣列標記相應節點是否連線過。low陣列的初始值用節點1到其餘各點的費用來填充 如該圖所示low陣列的初始值應該為 0634 5以上便是1號節點對於其他各點的費用 接下來在low陣列中尋找最小值 為3號節點費用為3最小。接著以3號節點為起始...