破圈法求解最小生成樹c語言實現(已驗證)

2021-09-11 07:30:11 字數 4227 閱讀 5064

破圈法求解最小生成樹c語言實現(已驗證)

下面是演算法偽**,每乙個演算法都取乙個圖作為輸入,並返回乙個邊集t。

對該演算法,證明t是一棵最小生成樹,或者證明t不是一棵最小生成樹。此外,對於每個演算法,無論它是否能計算出一棵最小生成樹,都要給出其最有效的實現。

maybe-mst-a(g,w)

sort the edges into nonincreasing order of edge weights w

tfor each edge e, taken in nonincreasing order by weight

do if t- is a connected graph

then t

return t

演算法基本思想:先將圖g的邊按照權的遞減順序排列後,依次檢驗每條邊,在保持連通的情況下,每次刪除最大權邊,直到所有邊都被遍歷到無法刪除任何一邊(或餘下n-1條邊為止)。證明:生成樹證明:1、如果給定連通圖g沒有迴路,那麼g本身就是一棵生成樹

2、如果g中只有乙個迴路,則刪去g的回路上的一條邊(不刪除節點),則產生的圖仍是連通的且沒有迴路,則得到的子圖就是g的一棵生成樹;

3、如果g的迴路不止乙個,只要刪去每乙個回路上的一條邊,知道g的子圖是連通且沒有迴路且與圖g有一樣的結點集,那麼這個子圖就是一棵生成樹。

4、重複步驟3,則直到所有邊都不能刪除,由於刪除判斷條件,得到的子圖就是一棵生成樹。

mst證明:

若在某個迴路c中有一條唯一的最長邊,則t­­­*中一定不含這條邊,因為優先刪除迴路中最長的邊。

若在某個邊e的割集中有一條唯一一條最短邊,則t*中一定含有這條邊(the cut property:考慮圖g中的一條邊e。如果存在乙個cut(a,b),使得e是所有跨越該割的所有邊中權重最小者,則e一定在g的mst中。

),且不含有其他邊,因為一旦含有其他邊就構成了迴路(lonely-cut corollary如果邊e是跨越了cut(a, b)的唯一一條邊,則e不可能在任一圈中。)。

反向證明:假設t*中跨越cut(a,b)的邊不只一條,則在演算法結束之前一定會遍歷到其中的成圈的邊(double-crossing),根據權值選取方法和刪除圈的一邊仍為連通圖的條件,一定會將權值較大的邊刪除,直到無環且剩下的唯一一條邊是最短邊。

演算法變數:

a[n][n]:帶權圖的鄰接矩陣,a[i][j]=w或a[i][j]=0;

max:標記當前找到的準備刪去的邊的權值;

p:標記找到的要刪去的權值所在的行號;

q:標記找到的要刪去的權值所在的列好;

am:標記找到的最大元素(am是為了保護權值大但不能刪的邊),如果a[i][j]不能刪除,則可以讓a[p][q]=am,a[q][p]=am來還原剛才刪去的邊;

i,j:二維陣列的行號和列號

sm:圖的邊數,每刪除乙個邊,sm就減1,當sm=n-1時,結束

wt:最小生成樹的權值和

演算法實現(c語言)

1 #includeby yuanshuai zheng,uestc

2 #define n 5

3 int a[n][n];

4 int flag,am,p,q;

5 input()

6 40 }

41 am = max;

42 printf("max=%5d\t",am);

43 p = ptm;

44 q = qtm;

45 a[p][q]=0;

46 a[q][p]=0;

47 }

48 wshall(int array[n][n])

49

65 }

66 for(j=0;j=1)

70

77 }

78 }

79 }

80 for(i=0;i=1)||(i==j))

103 // m=m+1;

104 // }

105 // }

106 // }

107 // printf("m=%d\t",m);

108 // if(m==n*n)

109 // flag = 1;

110 // else

111 // flag=0;

112 // return(flag);

113

114 int main()

115

126 }

127 printf("\nsm=%d\n",sm);

128 printf("輸出圖的帶權鄰接矩陣:\n");

129 output(a);

130 printf("\n");

131 while(sm>n-1)

132

142 else

143

147 }

148 }

149 for(i=0;i**驗證:

例子:

收藏

最小生成樹 kruskal演算法C語言實現

系列文章 最小生成樹 prim演算法c語言實現 時間複雜度 o nlogn n為邊數 kruskal演算法又稱 加邊法 用於邊數較少的稀疏圖 方法 每次找圖中權值最小的邊 此演算法中對於權值的排序運用了快速排序的方法 將邊連線的兩個頂點加入最小生成樹集合中 注意 相同權值任選其中乙個即可,但是不允許...

最小生成樹Prim演算法樸素版 C語言實現

前幾天研究kruskal演算法,直接上手就是並查集優化,樸素演算法壓根就沒寫。這兩天看prim演算法也想略過樸素版o n 2 直接用二叉堆優化,可是發現不看樸素演算法根本寫不出來.囧,看來還是不能忽略基礎.草稿紙上畫圖模擬推演了半天,終於搞清楚prim演算法樸素版的c語言實現,拿出那天學kruska...

C 實現最小生成樹

第一種 求最小生成樹,普里姆演算法 prim 先給定乙個初始點,然後找到離它最近的點,並加入找的點序列,將其對應的距離設為0 然後找其它頂點距離新的找到點集合最小的點,再加入找到的點序列 重複以上過程 public static void prim minitree graph g console....