练习四1001畅通工程

题意:第一行那是小镇的数目,下面三行分别是第一个小镇到第一个的距离,到第二个的距离,以此类推。再输入有几个联通的点集(生成树),再一行代表哪两个点连接。

思路:

1.用一个二维数组代表距离,并且形成了映射关系,a[m-1][n-1]代表m镇到n镇的距离。

2.就是求一个最小生成树,使用Kruskal算法,没到根节点不同的地方就将权值相加,输出即可

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 105;
int root[N];
int a[N][N];
int find(int x)//查找
{
    if (x != root[x])
        root[x] = find(root[x]);
    return root[x];
}
struct node
{
    int x, y, v;
}e[N*(N - 1) / 2];
int cmp(node e1, node e2)
{
    return e1.v<e2.v;
}
int main()
{
    int n;
    cin >> n;
    int m= n;
    for (int i = 0; i < n; ++i)
        root[i] = i;
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j)
            cin >> a[i][j];//a[i][j]表示每个点之间的距离
    int num;
    cin >> num;
    int x1, x2;
    for (int i = 0; i <num; ++i)//将以连接的点的距离赋0
    {
        cin >> x1 >> x2;
        a[x1 - 1][x2 - 1] = 0;
    }
    int t = 0;
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j)
        {
            e[t].x = i;
            e[t].y = j;
            e[t].v = a[i][j];
            ++t;
        }
    int sum = 0;
    sort(e, e +t, cmp);
    for (int i = 0; i <t; ++i)//合并
    {
        int x = find(e[i].x);
        int y = find(e[i].y);
        if (x != y)
        {
            sum+= e[i].v;
            root[x] = y;
            --m;//每次将m减一,作为flag

           if(m==1)
            {
                cout <<sum<< endl;
            }
        }

    }
    return 0;

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值