昨天做藍橋杯的題,最後一題最小生成樹,但好久沒用一下子生疏了。。。
又過了幾天離散學到了最小生成樹。。。趁此複習一波
最小生成樹兩種方法:
prim和kruskal
prim:該演算法的時間複雜度為o(n2)。與圖中邊數無關,該演算法適合於稠密圖。
kruskal:需要對圖的邊進行訪問,所以克魯斯卡爾演算法的時間複雜度只和邊又關係,可以證明其時間複雜度為o(eloge)。適合稀疏圖。
利用並查集來求
連通塊:無向圖中相互連通 的一些點
具體步驟:將乙個連通塊當做乙個集合,然後按照邊的大小(從小到大)進行排序,一開始認為每個點都是孤立的,自身是乙個集合。
然後按照順序列舉每乙個邊,如果這個邊連線了不同的集合,就用並查集將兩個集合合併在一起,就成乙個集合了。並將這條邊加入最小生成樹。如果這條邊連線的是乙個集合,就直接跳過,直到n-1條邊為止
#include
#include
#include
#include
#include
using
namespace std;
int n,m,i,j,u,v,total;
struct edgebian[
2000005];
int f[
100000];
long
long ans;
intfind
(int x)
//並查集部分
bool
cmp(edge a,edge b)
//結構體快排時用到的
inline
void
kruskal()
//最小生成樹
}int
main()
sort
(bian+
1,bian+m+
1,cmp)
;//快排邊長
kruskal()
;printf
("%d"
,ans)
;return0;
}
prim中白點代表已經進入最小生成樹的點,藍點代表未進入最小生成樹的二點
mst表示最小生成樹權值
min[v]表示藍點v與白點相連的最小邊權值
prim演算法每次回迴圈將乙個藍點u變成白點,並且此藍點與白點相連的最小邊權值min[u]還是當前所有藍點中最小的,這樣相當於向生成樹中新增了n-1次最小的邊,最後的到的肯定是最小生成樹
步驟:(a)初始化:min=inf min[1]=0 mst=0
(b)for列舉點
1.尋找min[u]最小的藍點u
2.將u標記為白點,說明已經進入最小生成樹
3.mst+這條邊min[u]
4.for列舉與u相連的藍點v
if(w[u][v]#include
using
namespace std;
#define re register
#define il inline
il int
read()
while
(c>=
'0'&&c<=
'9') x=
(x<<3)
+(x<<1)
+(c^48)
,c=getchar()
;return x*f;
}//快讀,不理解的同學用cin代替即可
#define inf 123456789
#define maxn 5005
#define maxm 200005
struct edge
e[maxm<<1]
;//注意是無向圖,開兩倍陣列
int head[maxn]
,dis[maxn]
,cnt,n,m,tot,now=
1,ans;
//已經加入最小生成樹的的點到沒有加入的點的最短距離,比如說1和2號節點已經加入了最小生成樹,那麼dis[3]就等於min(1->3,2->3)
bool vis[maxn]
;//鏈式前向星加邊
il void
add(
int u,
int v,
int w)
//讀入資料
il void
init()
}il int
prim()
//這裡要注意重邊,所以要用到min
for(re int i=head[1]
;i;i=e[i]
.next)
while
(++tot//最小生成樹邊數等於點數-1
} ans+
=minn;
//列舉now的所有連邊,更新dis陣列
for(re int i=head[now]
;i;i=e[i]
.next)}}
return ans;
}int
main()
最小生成樹模板
prim演算法理解可以參考部落格 prim演算法模板 int prime int v int i,j,sum 0,min,k sum是權重和 for i 1 i n i lowcost i 表明當前狀態下在u內距離v點 s中各點 距離的最小值,每個u中點s 中點 都計算 lowcost i map ...
最小生成樹 模板
const int maxn 1010 const int maxm 200020 struct edge edges maxm int father maxn int find int x int cmp edge a,edge b 將邊按權值排序 int kruskal int n,int m ...
模板 最小生成樹
題目描述 如題,給出乙個無向圖,求出最小生成樹,如果該圖不連通,則輸出orz 輸入輸出格式 輸入格式 第一行包含兩個整數n m,表示該圖共有n個結點和m條無向邊。n 5000,m 200000 接下來m行每行包含三個整數xi yi zi,表示有一條長度為zi的無向邊連線結點xi yi 輸出格式 輸出...