Highways最小生成树

Highways
原题链接https://vjudge.net/contest/352170#problem/G
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
题目给出n个地点以及n个地点的坐标,以及已经连接好的路,要求出连接剩下的路的最短路径需要连接的路,利用Kruskal正常记录路径,将已经连接的地点取出,进行特别连接,不记录,连接完成之后,在连接其他路径,并记录路径,最后将记录结果输出。
Kruskal:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <queue>
using namespace std;
long long n;
long long cnt;
long long z;
long long pre[300005];
struct node
{
    long long u;
    long long v;
    double w;
} stu[300005];
struct id
{
    long long x;
    long long y;
} idd[300005];
struct sum
{
    long long u;
    long long v;
} sum1[300005];
bool cmp(node x, node y)
{
    return x.w < y.w;
}
long long find(long long x)
{
    if (pre[x] == x)
    {
        return x;
    }
    return pre[x] = find(pre[x]);
}
void join(long long x, long long y, double w)
{
    long long ss1 = find(x);
    long long ss2 = find(y);
    if (ss1 != ss2)
    {
        pre[ss1] = ss2;
        cnt--;
        if (w != 0)
        {
            sum1[z].u = x;
            sum1[z].v = y;
            z++;
        }
    }
}
int main()
{
    cin >> n;
    long long i, j;
    z = 0;
    for (i = 1; i <= n; i++)
    {
        pre[i] = i;
        scanf("%lld %lld", &idd[i].x, &idd[i].y);
    }
    cnt = n;
    long long k = 0;
    for (i = 1; i < n; i++)
    {
        for (j = i + 1; j <= n; j++)
        {
            stu[k].u = i;
            stu[k].v = j;
            stu[k].w = sqrt(1.0 * (idd[i].x - idd[j].x) * (idd[i].x - idd[j].x) + 1.0 * (idd[i].y - idd[j].y) * (idd[i].y - idd[j].y));
            k++;
        }
    }
    long long m;
    long long a, b;
    sort(stu, stu + k, cmp);
    scanf("%lld", &m);
    while (m--)
    {
        scanf("%lld %lld", &a, &b);
        join(a, b, 0.0);//特别标记,不记录
    }
    for (i = 0; i < k; i++)
    {
        join(stu[i].u, stu[i].v, stu[i].w);//正常计算,
        if (cnt == 1)
        {
            break;
        }
    }
    for (i = 0; i < z; i++)
    {
        printf("%lld %lld\n", sum1[i].u, sum1[i].v);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值