图结构浅谈之prim算法

prim算法(基于贪心的算法)
#define n 10                      //图中顶点的个数
#define INF 100000000             //无穷大
void prim(float MGraph[][n],int v0,int &sum) {
    int v, k, min;                //v执行需要插入的结点,k执行最小边的另外一个顶点,min为无穷大,用于选择最小的边
    int lowcost[n];               //最短路径集
    int vset[n];                  //顶点集
    //初始化最短路径集和顶点集
    for (int i = 0; i < n; i++)
    {
        lowcost[i] = MGraph[v0][i];
        vset[i] = 0;
    }
    //将v0并入vset集
    v = v0;
    vset[v] = 1;
    sum = 0;                     //权和初始化
    for (int i = 0; i < n-1; i++)       //对其余n-1个顶点进行操作
    {
        min = INF;
        //找寻最小代价边
        for (int j = 0; j < n; j++)
        {
            if (lowcost[j]<min)
            {
                min = lowcost[j];
                k = j;
            }
        }
        vset[k] = 1;         //将k并入顶点集
        v = k;
        sum += min;
        //更新最小代价集
        for (int i = 0; i < n; i++)
        {
            if (vset[i]==0&&MGraph[v][i]<lowcost[i])
            {
                lowcost[i] = MGraph[v][i];
            }
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Prim算法是一种用于解决最小生成树问题的贪心算法。它的基本思想是从的某个顶点开始,不断选择与当前生成树相邻的、权值最小的边,直到生成一棵包含中所有顶点的最小生成树。 以下是Prim算法的基本步骤: 1. 选择任意一个顶点作为起始点,将该顶点加入到已经生成的树中。 2. 以已经生成的树中的所有顶点为起点,遍历它们所能到达的所有未加入到已经生成的树中的顶点,找到其中权值最小的边。 3. 将找到的权值最小的边所连接的顶点加入到已经生成的树中。 4. 重复步骤2和步骤3,直到生成一棵包含中所有顶点的最小生成树。 下面是Prim算法的C++实现代码: ```c++ #include <iostream> #include <vector> #include <queue> #include <cstring> using namespace std; const int N = 100010, INF = 0x3f3f3f3f; int n, m; int h[N], e[N], ne[N], w[N], idx; bool st[N]; int dist[N]; void add(int a, int b, int c) { e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++ ; } int prim() { memset(dist, 0x3f, sizeof dist); dist[1] = 0; int res = 0; priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> q; q.push({0, 1}); while (q.size()) { auto t = q.top(); q.pop(); int ver = t.second, distance = t.first; if (st[ver]) continue; st[ver] = true; res += distance; for (int i = h[ver]; ~i; i = ne[i]) { int j = e[i]; if (dist[j] > w[i]) { dist[j] = w[i]; q.push({dist[j], j}); } } } return res; } int main() { memset(h, -1, sizeof h); cin >> n >> m; while (m -- ) { int a, b, c; cin >> a >> b >> c; add(a, b, c), add(b, a, c); } cout << prim() << endl; return 0; } ``` 其中,h数组用于存放每个顶点的第一条边的编号,e数组和ne数组分别存放边的终点和下一条边的编号,w数组存放边的权值,idx表示边的数量。st数组表示一个顶点是否已经加入到了已经生成的树中,dist数组存放当前顶点到已经生成的树中的最短距离。优先队列q用于存放每个顶点到已经生成的树中的最短距离,每次从q中取出距离最小的顶点加入到已经生成的树中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值