// 贪心算法 最小生成树问题 - Prim算法
#include <iostream>
using namespace std;
#define M 9999 // maxint,inf,大数,无穷
const int N = 6;// 无向连通带权图的 顶点数
void Prim(int n, int c[][N + 1]);
int main()
{
// 无向连通带权图的邻接矩阵,行和列下标从1开始
int c[N + 1][N + 1] = {
{M, M, M, M, M, M, M},
{M, M, 8, 1, 5, M, M},
{M, 8, M, 3, M, 3, M},
{M, 1, 3, M, 5, 6, 4},
{M, 5, M, 5, M, M, 2},
{M, M, 3, 6, M, M, 6},
{M, M, M, 4, 2, 6, M},
};
cout << "无向连通带权图的矩阵为:\n";
for (int i = 1; i <= N; i++)
{
for (int j = 1; j <= N; j++){
if(c[i][j]==M)
{
cout << "INF" << "\t";
}
else{
cout << c[i][j] << "\t";
}
}
cout << endl;
}
cout << "\nPrim算法最小生成树选边次序:" << endl;
Prim(N, c);
return 0;
}
void Prim(int n, int c[][N + 1])
{
// 顶点j属于V-S,closest[j]是顶点j在S中的 最邻接顶点
int closest[N + 1]; // j的 最邻接顶点
// 顶点j属于V-S,顶点j到closest[j]和S中的其它邻接顶点k相比
// c[j][closest[j]] <= c[j][k],即最小权值
int lowcost[N + 1]; // 最小权值,c[j][closest[j]]
bool s[N + 1]; // 顶点集合S
s[1] = true; // 初始S={1}
//初始化
for (int i = 2; i <= n; i++)
{
closest[i] = 1;
lowcost[i] = c[1][i];
s[i] = false;
}
for (int i = 1; i < n; i++)
{
int min = M;
int j = 1;
// 找出V-S中使权值最小的顶点j
for (int k = 2; k <= n; k++)
{
if ((lowcost[k] < min) && (!s[k]))
{
min = lowcost[k];
j = k;
}
}
// 找到符合贪心选择方式的边,将顶点j加入到集合S
cout << closest[j] << "--" << j << endl;
s[j] = true;
// 找到一条边后,更新数组closest和lowcost
for (int k = 2; k <= n; k++)
{
if ((c[j][k] < lowcost[k] && (!s[k])))
{
lowcost[k] = c[j][k];
closest[k] = j;
}
}
}
}
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
目的: 1.掌握能用贪心法求解的问题应满足的条件; 2.加深对贪心法算法设计方法的理解与应用; 3.锻炼对程序跟踪调试能力; 4.练习培养应用所学知识解决实际问题的能力。 问题描述: 设G =(V,E)是无向连通带权图,即一个网络。(V是顶点集合,E是边集合)如果G的子图G’是一棵包含G的所有顶点的树,则称G’为G的生成树。生成树上各边权的总和称为该生成树的耗费。在G的所有生成树中,耗费最小的生成树称为G的最小生成树。 贪心选择策略: 每次都选择到下一顶点权最小的边。 基本步骤: 1.置顶点集合S={1}; 2.只要S是V的真子集,就作如下的贪心选择:选取满足条件i∈S,j∈V-S,且c[i][j]最小的边,将顶点j添加到S中。 3.这个过程一直进行到S=V时为止,选取到的所有边恰好构成G的一棵最小生成树。
资源推荐
资源详情
资源评论
收起资源包目录
贪心算法 prim.zip (2个子文件)
贪心算法.exe 2.46MB
贪心算法.cpp 2KB
共 2 条
- 1
资源评论
涣清。
- 粉丝: 51
- 资源: 4
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功