最小生成樹演算法

2022-09-02 22:12:20 字數 2583 閱讀 9554

最小生成樹是在圖中構造一棵無根樹,使所有點連同,且樹的邊權的和最小。一般是針對無向圖的,如果是有向圖的話,怎麼處理?這個東西的應用一般就是頂以上的,如果用到應該很容易看出來。對於動態處理邊的聯機演算法,貌似可以使用二叉堆來做卡魯斯卡爾,或者是每次加入邊時找出環,列舉來拆掉環中的邊,貌似需要尋找環,用深搜?最近公共祖先?

program primandkrskr;

const

maxn=500;

maxp=3000;

type by=record //邊表型別,用於克魯斯卡爾

r,a,b:longint;u:boolean;//分別是邊權,兩端和使用標誌

end;

varb:array[0..maxp] of by;

m,s:array[0..maxn,0..maxn] of longint;

tr:array[0..maxn] of longint;

n,p,i,j,t,tt:longint;

function prim(x:longint):longint;//普利姆演算法

vardist,port:array[0..maxn] of longint;//離樹的距離和接入樹的點

i,j,mm,mt:longint;

begin

prim:=0;//初始化代價

for i:=1 to n do begin//初始化,將每個點離樹的距離設為離初始點的距離(直接)(無法直接到達的是正無窮)

dist[i]:=m[x,i];

port[i]:=x;

end;

for j:=1 to n-1 do begin //加入n-1個點

mm:=maxlongint;//每次要初始化比較變數

for i:=1 to n do//列舉每個點

if (dist[i]<>0) and (dist[i]function krskr(x:longint):longint;//克魯斯卡爾演算法,基於排序和並查集,時間複雜度約為o(eloge),在稀疏圖中很快

varf:array[0..maxn] of longint;//並查集陣列

i,j,c,ct:longint;

function find(x:longint):longint;//並查集查詢

begin

if f[x]=x then begin

find:=x;

exit;

end;

find:=find(f[x]);

f[x]:=find;

end;

procedure com(x,y:longint);//並查集合並

varfx,fy:longint;

begin

fx:=find(x);fy:=find(y);

if fx<>fy then

f[fx]:=fy;

end;

procedure qs(s,e:longint);//快速排序

vari,j,m:longint;

t:by;

begin

i:=s;j:=e;m:=b[(i+j) shr 1].r;

repeat

while b[i].rm do dec(j);

if i<=j then begin

t:=b[i];

b[i]:=b[j];

b[j]:=t;

inc(i);dec(j);

end;

until i>j;

if is then qs(s,j);

end;

begin

for i:=1 to n do//並查集初始化

f[i]:=i;

qs(1,p);//對邊進行排序

ct:=0;//初始化已加入的邊數

krskr:=0;//初始化代價

for i:=1 to p do begin//列舉排序好的邊

if ct=n-1 then//如果已經完成生成樹則退出

break;

if find(b[i].a)<>find(b[i].b) then begin//如果並查集不在同一集合中,說明加入邊不會形成環

inc(ct);//增加邊數

b[i].u:=true;//記錄該邊

com(b[i].a,b[i].b);//合併便兩端的點所在集合

inc(krskr,b[i].r);//增加代價

end;

end;

end;

begin

readln(n,p);

for i:=1 to n do begin

for j:=1 to n do

m[i,j]:=maxlongint;

m[i,i]:=0;

end;

for i:=1 to p do begin

readln(t,tt,j);

m[t,tt]:=j;

m[tt,t]:=j;

b[i].r:=j;

b[i].a:=t;

b[i].b:=tt;

end;

writeln(prim(1));

writeln(krskr(1));

end.

最小生成樹演算法

由帶權的連通圖生成的數的各邊加起來稱為生成樹的權,把權值最小的生成樹稱為最小生成樹 minimum spanning tree 簡稱為mst 構造最小生成樹的方法就是利用mst性質,一條一條地選擇可以加入的邊。下面介紹兩種用於構造最小生成樹的演算法,其中第一種演算法稱為prim演算法,第二種演算法稱...

最小生成樹演算法

乙個最簡單的最小生成樹 圖結構練習 最小生成樹 time limit 1000ms memory limit 65536k 有n個城市,其中有些城市之間可以修建公路,修建不同的公路費用是不同的。現在我們想知道,最少花多少錢修公路可以將所有的城市連在一起,使在任意一城市出發,可以到達其他任意的城市。輸...

演算法 最小生成樹

前言 最小生成樹是在乙個給定的無向圖中求一棵樹,這棵樹包含無向圖中的所有頂點,且樹中的邊都來自無向圖中的邊,並且要滿足整棵樹的邊權之和最小。1 最小生成樹是樹,其邊數等於頂點數減1,且不會有環 2 對於給定的圖最小生成樹可以不唯一,但是邊權之和一定是唯一的。3 其根節點可以是這棵樹上的任何乙個節點,...