POJ - 1751Highways最小生成树kruskal

The island nation of Flatopia is perfectly flat. Unfortunately, Flatopia has a very poor system of public highways. The Flatopian government is aware of this problem and has already constructed a number of highways connecting some of the most important towns. However, there are still some towns that you can’t reach via a highway. It is necessary to build more highways so that it will be possible to drive between any pair of towns without leaving the highway system.
玄学,C++没过TLE了,G++过了。
用了kruskal。
把已连接的点先放到树里就可以了。

#include <stdio.h>
#include <string.h>
#include <iostream>
#include<algorithm>
#include <vector>
#include <queue>
#include <string>
#include <math.h>
#include <stdlib.h>
using namespace std;
#define INF 0x3f3f3f3f
#define mem(arr,a) memset(arr,a,sizeof(arr))
#define V 800
#define LL long long int
#define E 320000
#define pow(a) ((a)*(a))
struct edge{
    LL u, v;
    LL w;
};
struct node{
    int x, y;
};
node vet[V];
edge es[E];
bool cmp(edge a, edge b){
    if (a.w!=b.w)
    return a.w < b.w;
    if (a.u != b.u)
        return a.u < b.u;
    return a.v < b.v;
}
int n, m;
int par[V];
int e = 0;
int find(int x){
    if (par[x] == x)return x;
    return par[x] = find(par[x]);
}



int main(){
    cin >> n;
    for (int i = 1; i <= n; i++)par[i] = i;
    for (int i = 1; i <= n; i++){
        scanf("%lld%lld", &vet[i].x, &vet[i].y);
    }
    for (int i = 1; i <= n; i++){
        for (int j = 1; j < i; j++){
            es[e].u = i, es[e].v = j, es[e++].w = pow(vet[i].x - vet[j].x) + pow(vet[i].y - vet[j].y);
        }
    }
    cin >> m;
    for (int i = 0; i < m; i++){
        int a, b; scanf("%d%d", &a, &b);
        a = find(a); b = find(b);
        par[a] = b;
    }
    sort(es, es + e, cmp);
    for (int i = 0; i < e; i++){
        int u = find(es[i].u);
        int v = find(es[i].v);
        if (u!=v){
            par[u] = v;
            printf("%lld %lld\n", es[i].u, es[i].v);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值