铺设网络(最小生成树)

某大学要建设无线校园网工程,现已规划好了无线网络终端的位置,你需要设计一份代价最小的方案,使各个无线网络终端设备相互连通。每两个无线网络终端的距离不会超过100000.

输入
第一行:终端的个数,N(3<=N<=100)。
第二行..结尾:后来的行包含了一个N*N的矩阵,表示每个终端之间的距离。理论上,他们是N行,每行由N个用空格分隔的数组成,实际上,他们限制在80个字符,因此,某些行会紧接着另一些行。当然,对角线将会是0,因为不会有线路从第i个终端到它本身。

输出
只有一个输出,其中包含连接到每个终端的光纤的最小长度。

输入样例
Copy
4
0 4 9 21
4 0 8 17
9 8 0 16
21 17 16 0
输出样例
Copy
28

#include <bits/stdc++.h>
using namespace std;

int fa[105]={0};

struct edge
{
    int u,v,e;
}edges[1000005];

bool cmp(edge a,edge b)
{
    return a.e<b.e;
}

int find(int a)
{
    if(fa[a]==a)
        return a;
    return fa[a]=find(fa[a]);
}
void merge(int a,int b)
{
    if(find(a)!=find(b))
        fa[find(a)]=b;
}

bool same(int a,int b)
{
    return find(a)==find(b);
}
int main()
{
    int n,k=0,sum=0;
    int a[105][105];
    cin>>n;
    for(int i=0;i<n;i++)
    {
        fa[i]=i;
    }
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            cin>>a[i][j];
        }

    }
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<i;j++)
            if(a[i][j]!=0)
            {

                edges[k].u=i;
                edges[k].v=j;
                edges[k].e=a[i][j];
                k++;
            }
    }
    sort(edges,edges+k,cmp);
    int t=n,num=k,p=0;
    while(t>1||num>0)
    {

        int uu=edges[p].u;
        int vv=edges[p].v;
        if(!same(uu,vv))
        {
            merge(uu,vv);
            sum+=edges[p].e;
        }

        t--;
        num--;
        p++;
    }
    cout<<sum;
    return 0;

}

其实是超级简单的,其函数包括查找根结点,合并,判断是否为同一个树内结点(及是否为亲戚),主要用了两个结构,一个是父亲数组fa[],初始时都是指向自身,可以在查找祖先的同时缩短路径,将每个点的父亲改为祖先。另一个是记录边和点的数组edges[],先对其进行排序(由小到大),然后依次去最小的,如果边的两个点已经放在了同一个集合中,就不必再合并,否则,合并这两个集合(同时路径长度+=此边的长度),最终所有的集合成为了一个大的集合,即最小生成树。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值