POJ 1861 Network Kruskal优化模板

题目链接:

1861




题意:

有M个点  N条边  求构成最小生成树的最大边   和生成树所有边的两个端点




裸最小生成树    加上了两个优化

1.路径压缩:查找x元素的根节点d时,将x的所有父亲节点全部直接变成根节点的子节点

以减少下次查找的查找时间

2.在并查集  并 的过程中 考虑两个节点谁的子节点多,少的作为子节点

关于fa[]数组:只有集合的根节点为负数,而且负数的绝对值表示该集合的元素个数(-1累加上去的);如果x不是根节点,则fa[x]表示x的父节点




代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node{
   int u,v,w;
}edge[16005];
int fa[1005],ans[1005][2];
int maxx,m,n,s,nn;
int cmp(node a,node b)
{
    return a.w<b.w;
}
void init()
{
    s=0,maxx=0,nn=0;
    memset(fa,-1,sizeof(fa));
}
int find(int x)
{
    int t,d=x;
    while(fa[d]>=0)
        d=fa[d];
    while(x!=d)
    {
        t=fa[x];
        fa[x]=d;
        x=t;
    }
    return d;                        
}
void Kruskal()
{
    int r1,r2,i,j,k;
    for(i=0;i<s;i++)
    {
        r1=find(edge[i].u);r2=find(edge[i].v);       
        if(r1!=r2)
        {
            if(edge[i].w>maxx)
                maxx=edge[i].w;
            ans[nn][0]=edge[i].u;ans[nn++][1]=edge[i].v;
            int ss=fa[r1]+fa[r2];
            if(fa[r1]<fa[r2])
            {
                fa[r1]=ss;
                fa[r2]=r1;
            }
            else
            {
                fa[r1]=r2;
                fa[r2]=ss;
            }
        }
        if(nn==m-1)
            break;
    }

    return ;
}
int main()
{
    int a,b,c,i;
    while(~scanf("%d%d",&m,&n))
    {
        init();
        while(n--)
        {
            scanf("%d%d%d",&a,&b,&c);
            edge[s].u=a;edge[s].v=b;
            edge[s++].w=c;
        }
        sort(edge,edge+s,cmp);
        Kruskal();
        cout<<maxx<<endl<<nn<<endl;
        for(i=0;i<nn;i++)
            cout<<ans[i][0]<<' '<<ans[i][1]<<endl;
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值