标签:一个起点 算法思想 组成 void 算法 最小生成树 visit amp break
Prim算法的思想是:
int adjMax[MAXN][MAXN]; //邻接矩阵
int n; //顶点数目
int pos = 0, ans = 0;
bool visited[MAXN] = {0}, cost[MAXN];
void Prim()
{
for (int i = 0; i < n; i++)
{
cost[i] = adjMax[0][i]; //集合u与集合V-u中的i点间距离最小值
visited[i] = false;
}
visited[0] = true; //已经在MST中
for (int i = 1; i < n; i++) //再找n-1个点
{
//找到连接u和V-u的最小边并记录位置
int tmp = INT_MAX;
for (int j = 0; j < n; j++)
{
if (visited[j] == false && cost[j] < tmp)
{
tmp = cost[j];
pos = j;
}
}
ans += tmp;
visited[pos] = true;
//加入某点后,V-u中的点j到u的距离可能变短,故更新cost[j]
for (int j = 0; j < n; j++)
{
if (visited[j] == false && cost[j] > adjMax[pos][j])
{
cost[j] = adjMax[pos][j];
}
}
}
}
性能:邻接矩阵表示不依赖于边数,复杂度\(O(|V|^2)\),适合边稠密的图。
该算法思想:将所有边的权值递增排序,如果加入某边后不构成回路,则将该边加入MST,直到MST中有\(n-1\)条边或\(n\)个顶点:
//用结构体存储边的信息
struct edge {
int start, des;
int val;
}edge[MAXN];
//用并查集判断有没有环
int UFSets[MAXN];
for (int i = 0; i < n; i++)
{
UFSets[i] = -1;
}
//在S中查找并返回包含x的树的根
int find(int S[],int x)
{
while (S[x] >= 0)
x = S[x];
return x;
}
void kruskal()
{
for (int i = 0; i < m; i++)
{
int u = find(UFSets, edge[i].start);
int v = find(UFSets, edge[i].des);
if (u == v) //edge[i]的两端点有相同的祖先,成环
continue;
ans += edge[i].val;
UFSets[u] = v; //合并两个并查集
cnt++;
if (cnt == n - 1)
break;
}
}
性能:复杂度\(O(ElogE)\),适合边稀疏、顶点多的图。
标签:一个起点 算法思想 组成 void 算法 最小生成树 visit amp break
原文地址:https://www.cnblogs.com/EIMadrigal/p/12234280.html