prim+heap模板

先扔在这里,还没具体搞懂

#include<bits/stdc++.h>

#define MAXN 1200
#define MAXM 120000
#define INF 19930317

int e[MAXM], cost[MAXM], next[MAXM], g[MAXN], size;

struct node
{
    int d, v;
}heap[MAXN];
int pos[MAXN], hl;
int m, n;
void swap(int a, int b)
{
    heap[0] = heap[a];
    heap[a] = heap[b];
    heap[b] = heap[0];
    pos[heap[a].v] = a;
    pos[heap[b].v] = b;
}
void heapfy()
{
    int i = 2;
    while (i <= hl)
    {
        if ((i < hl) && (heap[i + 1].d < heap[i].d))
            i++;
        if (heap[i].d < heap[i >> 1].d)
        {
            swap(i, i >> 1);
            i <<= 1;
        }
        else
            break;
    }
}

void decrease(int i)
{
    heap[0] = heap[i];
    while ((i > 1) && (heap[0].d < heap[i >> 1].d))
    {
        heap[i] = heap[i >> 1];
        pos[heap[i].v] = i;
        i >>= 1;
    }
    heap[i] = heap[0];
    pos[heap[i].v] = i;
}

void delete_min()
{
    swap(1, hl);
    hl--;
    heapfy();
}

void relax(int v, int w)
{
    if (w < heap[pos[v]].d)
    {
        heap[pos[v]].d = w;
        decrease(pos[v]);
    }
}

void insert(int u, int v, int w)
{
    e[++size] = v;
    cost[size] = w;
    next[size] = g[u];
    g[u] = size;
}

void init()
{
    int i, u, v, w;

    size = 0;
    memset(g, 0, sizeof(g));
    for (i = 1; i <= m; i++)
    {
        scanf("%d%d%d", &u, &v, &w);
        insert(u, v, w);
        insert(v, u, w);
    }
}

int prim()
{
    int mst = 0, u , p, i;

    for (i = 1; i <= n; i++)
    {
        pos[i] = heap[i].v = i;
        heap[i].d = INF;
    }
    heap[1].d = 0;
    hl = n;
    while (hl)
    {
        u = heap[1].v;
        mst += heap[1].d;
        delete_min();
        for (p = g[u]; p; p = next[p])
            if (pos[e[p]] <= hl)
                relax(e[p], cost[p]);
    }
    return mst;
}

int main()
{
    while (scanf("%d%d", &n, &m) == 2 && n)
    {
        init();
        printf("%d\n", prim());
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值