破圈法求解最小生成樹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....