poj 1287 networking kruskal

本文详细介绍了Kruskal算法在解决最小生成树问题中的应用,包括算法的基本思想、实现步骤及核心代码。通过使用并查集高效地处理节点关系,确保了算法能够正确地找出图中所有节点间的最短总路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

         题目:点击打开链接

 

#include<algorithm>
#include<stdio.h>
#include<string.h>
#define MAX 60
#define INF 0x3f3f3f3f
using namespace std;
struct edge{
    int u,v,dis;
}e[MAX*MAX/2];//边
int n,fa[60],g[60][60];
void init()//并查集初始化
{
    for(int i=0;i<=n;++i)
        fa[i]=i;
}
int findd(int x)//找到根父节点
{
    if(fa[x]!=x)
        fa[x]=findd(fa[x]);
    return fa[x];
}
void unionn(int tu,int tv)//连接两个节点
{
    int fau=findd(tu);
    int fav=findd(tv);
    fa[fav]=fau;
}
bool comp(const edge& e1,const edge& e2)//运算符重载
{
    return e1.dis<e2.dis;
}
int kruskal(int en)
{
    sort(e,e+en,comp);//把边从小到大排序
    int res=0;//计路径总长
    for(int i=0;i<en;++i)
    {
        edge nowe=e[i];
        if(findd(nowe.u)!=findd(nowe.v))//如果当前边所连接的两个点没有关系,使他们发生关系
        {
            unionn(nowe.u,nowe.v);
            res+=nowe.dis;
        }
    }
    return res;
}
int main()
{
    int en,q,a,b,c,m;
    while(scanf("%d",&n)&&n)
    {
        en=0;
        scanf("%d",&m);
        memset(g,INF,sizeof(g));
        while(m--)
        {
            scanf("%d%d%d",&a,&b,&c);
            if(g[min(a,b)][max(a,b)]>c)
                g[min(a,b)][max(a,b)]=c;
        }//由于两点间有多种可能,所以先写进二维数组找到两点间(直接)最短的边
        for(int i=1;i<n;++i)
        {
            for(int j=i+1;j<=n;++j)
            {
                if(g[i][j]!=INF)
                {
                    e[en].u=i;
                    e[en].v=j;
                    e[en].dis=g[i][j];
                    ++en;
                }
            }//把数组中的边写进邻接表
        }
        init();
        printf("%d\n",kruskal(en));
    }
    return 0;
}


kruskal算法用到了并查集这种高效的查找方式,并查集发生的过程是生成数的过程,由小树变成大树的过程,当判断两个元素是否有关系时实际在判断两个元素是否属于同一棵树的过程。sort函数用来排结构体很方便,算法的核心用贪心的思想要找最短总路径,每一步都选择当期最短的路,直到连接所有节点。

 

 

 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值