概念:將給出的所有點連線起來(即從乙個點可到任意乙個點),且連線路徑之和最小的圖叫最小生成樹。最小生成樹屬於一種樹形結構(樹形結構是一種特殊的圖),或者說是直鏈型結構,因為當n個點相連,且路徑和最短,那麼將它們相連的路一定是n-1條。
可以利用參考乙個問題理解最小生成樹,有n個村莊,每個村莊之間距離不同,要求村莊之間修路,每乙個村莊必須與任意乙個村莊聯通,如何修路最省錢(修的最短)
利姆(prim)演算法求最小生成樹,也就是在包含n個頂點的連通圖中,找出只有(n-1)條邊包含所有n個頂點的連通子圖,也就是所謂的極小連通子圖
具體過程如下:
(1)設g=(v,e)是連通網,t=(u,d)是最小生成樹,v,u是頂點集合,e,d是邊的集合
(2)若從頂點u開始構造最小生成樹,則從集合v中取出頂點u放入集合u中,標記頂點v的visited[u]=1
(3)若集合u中頂點ui與集合v-u中的頂點vj之間存在邊,則尋找這些邊中權值最小的邊,但不能構成迴路,將頂點vj加入集合u中,將邊(ui,vj)加入集合d中,標記visited[vj]=1
(4)重複步驟②,直到u與v相等,即所有頂點都被標記為訪問過,此時d中有n-1條邊
不同的題目有不同的細節實現方式,因此本**僅供參考
#include #include#define n 20
#define maxnum 10000 /*定義乙個最大整數*/
/*定義鄰接矩陣型別
*/typedef
int adjmatrix[n + 1][n + 1
];
typedef
struct
edge;
typedef edge *edgenode; //
定義生成樹的別名
int arcnum; /*
邊的個數
*//*
建立圖的鄰接矩陣
*/void
creatmatrix(adjmatrix ga)
else}}
printf(
"請輸入邊的個數:\n");
scanf("%d
", &arcnum);
printf(
"請輸入邊的資訊,依照起點,終點,權值的形式輸入:\n");
for(k=1; k<=arcnum; k++) }
/*初始化圖的邊集陣列
*/void initedge(edgenode ge,int
m) }
/*依據圖的鄰接矩陣生成圖的邊集陣列
*/void
getedgeset(adjmatrix ga,edgenode ge)
}}}
/*按公升序排列圖的邊集陣列
*/void sortedge(edgenode ge,int
m) }
if(k!=i)
}}
/*利用普里姆演算法從初始點v出發求鄰接矩陣表示的圖的最小生成樹
*/void
prim(adjmatrix ga,edgenode t)
}/*進行n-1次迴圈,每次求出最小生成樹中的第k條邊
*/for(k=1; k)
}/*把最短邊對調到k-1下標位置
*/可用swap替換
temp=t[k];
t[k]=t[m];
t[m]=temp;
/*把新增加最小生成樹t中的頂點序號賦給j
*/j=t[k].tovex;
/*改動有關邊,使t中到t外的每個頂點保持一條到眼下為止最短的邊
*/for(i=k+1; i)
}}}
/*輸出邊集陣列的每條邊
*/void outedge(edgenode ge,int
e) printf(
"*************************====\n");
} intmain()
最小生成樹之prim 普利姆 演算法
求最小生成樹 prim演算法 1000 ms 10000 kb 1726 3439 tags 生成樹 求出給定無向帶權圖的最小生成樹。圖的定點為字元型,權值為不超過100的整形。在提示中已經給出了部分 你只需要完善prim演算法即可。輸入第一行為圖的頂點個數n 第二行為圖的邊的條數e 接著e行為依附...
Prim(普利姆)演算法求最小生成樹 O N 2
給定乙個n個點m條邊的無向圖,圖中可能存在重邊和自環,邊權可能為負數。求最小生成樹的樹邊權重之和,如果最小生成樹不存在則輸出impossible。給定一張邊帶權的無向圖g v,e 其中v表示圖中點的集合,e表示圖中邊的集合,n v m e 由v中的全部n個頂點和e中n 1條邊構成的無向連通子圖被稱為...
最小生成樹 普里姆演算法 Prim
最小生成樹 的7到12行先初始化了矩陣第一行的值,本來很奇怪,那其他行的值怎麼辦?看到最後的28 35行才知道,原來從下面開始會逐步初始化與上個頂點相關的邊的值,最後能夠把全部都初始化了。截圖如下 演算法定義 1 輸入 乙個加權連通圖,其中頂點集合為v,邊集合為e 2 初始化 v new 其中x為集...