Prim算法
-
描述:普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树。意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (graph theory)),且其所有边的权值之和亦为最小。该算法于1930年由捷克数学家沃伊捷赫·亚尔尼克(英语:Vojtěch Jarník)发现;并在1957年由美国计算机科学家罗伯特·普里姆(英语:Robert C. Prim)独立发现;1959年,艾兹格·迪科斯彻再次发现了该算法。因此,在某些场合,普里姆算法又被称为DJP算法、亚尔尼克算法或普里姆-亚尔尼克算法。
-
图形描述:Prim百度百科
代码展示:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 500, inf = 0x3f3f3f3f; //inf表示极大值
int n; //n个地点
int Map[maxn][maxn], lw[maxn], vis[maxn];
/*
* Map是一个矩阵,存的是图,Map[a][b]就是a到b的距离,lw代表i到集合V的距离,vis是标记i是否在V中
*/
void Prim()
{
int m, a, b, c; //m为条数,a,b,c为起始,终止,还有权值
while (cin >> n)
{
//初始化Map地图
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
Map[i][j] = i == j ? 0 : inf;
}
}
//m条路
cin >> m;
for (int i = 0; i < m; i++)
{
cin >> a >> b >> c;
//和最短路径差不多
if (Map[a][b] > c)
Map[a][b] = Map[b][a] = c;
}
//算法开始
int sum = 0; //路长
memset(vis, 0, sizeof vis); //初始化标记数组
vis[a] = 1; //把a点作为起始点
//初始化lw数组
for (int i = 1; i <= n; i++)
{
lw[i] = Map[i][a];
}
lw[a] = 0; //特殊点
//循环n-1次
for (int i = 0; i < n - 1; i++)
{
int minn = inf, u; //中间变量
//为了找到每一次循环的最小值
for (int j = 1; j <= n; j++)
{
if (!vis[j] && lw[j] < minn)
{
minn = lw[j];
u = j;
}
}
vis[u] = 1; //把u放入集合中
lw[u] = 0; //更新lw
sum += minn;
//更新lw
for (int j = 1; j <= n; j++)
{
if (!vis[j] && lw[j] > Map[j][u])
lw[j] = Map[j][u];
}
}
cout << sum << endl;
}
}
int main()
{
return 0;
}