朱刘模版




int ZL_MST(int ROOT)
{
    int RTANS = 0;
    while (1)
    {
        for (int i =0 ; i < N; i ++) IN[i] = INF;
        for (int i = 0; i < EDGENUMBER;i ++)//m条边
        {
            int U = EDGE[i].U;int V = EDGE[i].V;
            if (U != V && EDGE[i].VALUE < IN[V])//除自环
            {
                PRE[V] = U;//父亲
                IN[V] = EDGE[i].VALUE;//这个点的最小权值
            }
        }
        for (int i = 0; i < N;i ++) if (i != ROOT && IN[i] == INF) return -1;//独立点(不能构成树
        int CNT = 0;IN[ROOT] = 0;//cnt新的点
        memset(COL, -1, sizeof(COL)); memset(ID, -1, sizeof(ID));//col 染色 id 点编号
        for (int i = 0; i < N;i ++)
        {
            RTANS += IN[i];
            int V = i;
            while (COL[V] != i && ID[V] == -1 && V != ROOT)
            {
                COL[V] = i;//向上染色
                V = PRE[V];//父亲
            }
            if (ID[V] == -1 && V != ROOT)//这个父点如果不是根结点的话,并且这个点没被编过号
            {
                for (int i = PRE[V]; i != V;i = PRE[i]) ID[i] = CNT;
                //关于这个点整个树的cnt
                ID[V] = CNT ++;
            }
        }
        if (!CNT) break;//如果没有环的话
        for (int i = 0; i < N;i ++) if (ID[i] == -1) ID[i] = CNT ++;
        for (int i = 0; i < EDGENUMBER;i ++)
        {
            int V = EDGE[i].V;
            EDGE[i].U = ID[EDGE[i].U];
            EDGE[i].V = ID[EDGE[i].V];
            if (EDGE[i].U != EDGE[i].V) EDGE[i].VALUE -= IN[V];//减去环中不需要的权值
        }
        N = CNT;//n为缩过的点
        ROOT = ID[ROOT];//根结点要变
    }
    return RTANS;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值