最小生成樹與最短路徑演算法

2021-08-07 08:47:17 字數 2623 閱讀 9003

最小生成樹(

prime

演算法、kruskal

演算法)和

最短路徑演算法(

floyd

、dijkstra

帶權圖分為有向和無向,無向圖的最短路徑又叫做最小生成樹,有prime演算法和kruskal演算法;有向圖的最短路徑演算法有dijkstra演算法和floyd演算法。

生成樹的概念:聯通圖g的乙個子圖如果是一棵包含g的所有頂點的樹,則該子圖稱為g的生成樹 生成樹是聯通圖的極小連通子圖。所謂極小是指:若在樹中任意增加一條邊,則 將出現乙個迴路;若去掉一條邊,將會使之程式設計非連通圖。生成樹各邊的權 值總和稱為生成素的權。權最小的生成樹稱為最小生成樹,常用的演算法有prime演算法和kruskal演算法。

最短路徑問題旨在尋找圖中兩節點之間的最短路徑,常用的演算法有:floyd演算法和dijkstra演算法。

構造最小生成樹一般使用貪心策略,有prime演算法和kruskal演算法

prime

演算法的基本思想

1.清空生成樹,任取乙個頂點加入生成樹

2.在那些乙個端點在生成樹里,另乙個端點不在生成樹里的邊中,選取一條權最小的邊,將它和另乙個端點加進生成樹

3.重複步驟2,直到所有的頂點都進入了生成樹為止,此時的生成樹就是最小生成樹

int prime(int cur)

for(int i = 1; i < m; i ++)

}visit[index] = true;

sum += mincost;

for(int j = 0; j < m; j ++)

}

} return sum;

}

kruskal

演算法:構造乙個只含n個頂點,而邊集為空的子圖,若將該子圖中各個頂點看成是各棵樹的根節點,則它是乙個含有n棵樹的森林 。之後,從網的邊集中選取一條權值最小的邊,若該邊的兩個頂點分屬不同的樹 ,則將其加入子圖,也就是這兩個頂點分別所在的 兩棵樹合成一棵樹;反之,若該邊的兩個頂點已落在同一棵樹上,則不可取,而應該取下一條權值最小的邊再試之。依次類推,直至森林只有一棵樹。kruskal演算法能夠在並查集的基礎很快的實現。

#include#includeusing namespace std;

const int size = 128;

int n;

int father[size];

int rank[size];

//把每條邊成為乙個結構體,包括起點、終點和權值

typedef struct node

edge[size * size / 2];

//把每個元素初始化為乙個集合

void make_set()

return ;

}//查詢乙個元素所在的集合,即找到祖先

int find_set(int x)

return father[x];

}//合併x,y所在的兩個集合:利用find_set找到其中兩個

//集合的祖先,將乙個集合的祖先指向另乙個集合的祖先。

void union(int x, int y)

if(rank[x] < rank[y])

else

father[y] = find_set(x);

}return ;

}bool cmp(pnode a, pnode b)

int kruskal(int n) //n為邊的數量

}return sum;

}int main()

char x, y;

int m, weight;

int cnt = 0;

for(int i = 0; i < n - 1; i ++)

}sort(edge, edge + cnt, cmp); //對邊按權從小到大排序

cout << kruskal(cnt) << endl;

}

}

最短路徑問題旨在尋找圖中兩節點之間的最短路徑,常用的演算法有:floyd演算法和dijkstra演算法。

floyd

演算法是最簡單的最短路徑演算法,可以計算圖中任意兩點間的最短路徑  folyd演算法的時間複雜度是o(n3),如果是乙個沒有邊權的圖,把相連的兩點  間的距離設為dist[i][j] = 1,不相連的兩點設為無窮大,用 floyd演算法可以判斷i,j兩點是否有路徑相連。

void floyd()

}

}

}

}

dijkstra演算法

用來計算從乙個點到其他所有點的最短路徑的演算法,複雜度o(n2)。

void dijkstra(int s)   //s是起點

int index;

for(int i = 1; i < n; i ++)

}visit[index] = true;

for(int j = 0; j < n; j ++)

}

}}

最短路徑與最小生成樹

19.8.9 總結 上午深入理解floyd演算法 就是將每一點都遍歷過去 然後選最短的 先理解最短路徑的一種演算法 有點難搞 下午測試 基礎不太行 以前寫的也有些忘了 晚上學最小生成樹 一開始難以理解 但看了各種部落格後漸漸理解 最後思路逐漸清晰 prim演算法就是 先將起點加入生成樹 然後從起點開...

最短路徑 最小生成樹

題目描述 n個城市,標號從0到n 1,m條道路,第k條道路 k從0開始 的長度為2 k,求編號為0的城市到其他城市的最短距離 輸入描述 第一行兩個正整數n 2 n 100 m m 500 表示有n個城市,m條道路 接下來m行兩個整數,表示相連的兩個城市的編號 輸出描述 n 1行,表示0號城市到其他城...

最短路徑 最小生成樹

今天覆習的時候,剛好複習的這一塊,所以就簡單做乙個備忘,寫的潦草還望大家不要介意呀 1 dijistra演算法 思路 根據點集合將其分為兩個集合,一種是已經訪問過的點s集合 代表從源點到該集合中的點的距離最小 另一種是未訪問過的u集合,然後每次從u集合中選擇節點,使得源點到改點的距離最小,並新增進s...