普利姆(prime)演算法(只與頂點相關)
演算法描述:
普利姆演算法求最小生成樹時候,和邊數無關,只和定點的數量相關,所以適合求稠密網的最小生成樹,時間複雜度為o(n*n)。
演算法過程:
1.將乙個圖的頂點分為兩部分,一部分是最小生成樹中的結點(a集合),另一部分是未處理的結點(b集合)。
2.首先選擇乙個結點,將這個結點加入a中,然後,對集合a中的頂點遍歷,找出a中頂點關聯的邊權值最小的那個(設為v),將此頂點從b中刪除,加入集合a中。
3.遞迴重複步驟2,直到b集合中的結點為空,結束此過程。
4.a集合中的結點就是由prime演算法得到的最小生成樹的結點,依照步驟2的結點連線這些頂點,得到的就是這個圖的最小生成樹。
演算法實現具體過程:
1.將第乙個點放入最小生成樹的集合中(標記visit[i]=1意思就是最小生成樹集合)。
2.從第二個點開始,初始化lowcost[i]為跟1點相連(僅僅相連)的邊的權值(lowcost[i]不是這個點的最小權值!在以後會逐步更新)。
3.找最小權值的邊。
從第二點開始遍歷,如果不是最小生成樹的集合的點,則找出從2到n的最小權值(lowcost[j])。
4.將找出來的最小權值的邊的頂點加入最小生成樹的集合中(標記visit[i] = 1),權值想加。
5.更新lowcost[j]集合。
假設第一次:lowcost[2]代表與1相連的點的權值,現在加入了k點。則比較k點與2點的邊map[k][2]和lowcost[2]的大小,若lowcost[2]大,則lowcost[2] = map[k][2]。(關鍵步驟:實質就是每在最小生成樹集合中加入乙個點就需要把這個點與集合外的點比較,不斷的尋找兩個集合之間最小的邊)
6.迴圈上述步驟,指導將全部頂點加入到最小生成樹集合為止。
**如下:
#include#include#include#include#includeusing namespace std;
#define inf 0x3f3f3f3f
#define maxn 110
int map[maxn][maxn], lowcost[maxn];
bool visit[maxn];
int nodenum, sum;
void prim()
}int main()
prim();
printf("%d\n", sum); //最小生成樹權值之和
} return 0;
}
普利姆演算法
演算法思想 可取圖中任意乙個頂點v作為生成樹的根,之後若要往生成樹上新增頂點w,則在頂點v和w之間必定存在一條邊。並且該邊的權值在所有連通頂點v和w之間的邊中取值最小。一般情況下,假設n個頂點分成兩個集合 u 包含已落在生成樹上的結點 和v u 尚未落在生成樹上的頂點 則在所有連通u中頂點和v u中...
普利姆演算法
普利姆 prim 這個演算法有什麼用?在實際中這個演算法經常用到電子板的電路連線中,因為可以使用到最少的連線將所有的電子連線起來,又打個比方在鋪設電線將所有使用者連線起來可以使用最少的電線連線起來 知道了這個作用之後你是不是比較感興趣呢?首先看 prim演算法生成最小生成樹 void minispa...
普利姆演算法
演算法思想 可取圖中任意乙個頂點v作為生成樹的根,之後若要往生成樹上新增頂點w,則在頂點v和w之間必定存在一條邊。並且該邊的權值在所有連通頂點v和w之間的邊中取值最小。一般情況下,假設n個頂點分成兩個集合 u 包含已落在生成樹上的結點 和v u 尚未落在生成樹上的頂點 則在所有連通u中頂點和v u中...