题目内容

FJ 已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场。为了用最小的消费,他想铺设最短的光纤去连接所有的农场。

你将得到一份各农场之间连接费用的列表,你必须找出能连接所有农场并所用光纤最短的方案。每两个农场间的距离不会超过 10^5

解题思路

农场之间要联通,使得光缆最小,所以要用最小生成树,跑一遍 Kruskal 就可以了。

代码:

#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

const int maxn=105;

struct unionset
{
    int bin[maxn];
    unionset()
    {
        for(int i=1;i<=maxn;i++)
            bin[i]=i;
    }
    int anc(int x)
    {
        if(bin[x]!=x)
            return bin[x]=anc(bin[x]);
        return bin[x];
    }
    void uni(int x,int y)
    {
        bin[anc(x)]=anc(y);
    }
    bool query(int x,int y)
    {
        return anc(x)==anc(y);
    }
}u;

struct edge
{
    int from,to,dist;
    edge(){}
    edge(int _from,int _to,int _dist)
    {
        this->from=_from;
        this->to=_to;
        this->dist=_dist;
    }
};

int n;
vector<edge> v;

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

int kruskal()
{
    int ans=0;
    sort(v.begin(),v.end(),cmp);
    for(auto e:v)
    {
        if(!u.query(e.from,e.to))
        {
            u.uni(e.from,e.to);
            ans+=e.dist;
        }
    }
    return ans;
}

int main()
{
    scanf("%d",&n);
    int tmp;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        {
            scanf("%d",&tmp);
            if(tmp)
                v.push_back(edge(i,j,tmp));
        }
    printf("%d\n",kruskal());
    return 0;
}
最后修改日期:2020年3月2日

作者

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。