【POJ 2349】Arctic Network(Kruskal算法)

题目链接:http://poj.org/problem?id=2349

题意:

有S颗卫星和P个哨所,有卫星的两个哨所之间可以任意通信;否则,一个哨所只能和距离它小于等于D的哨所通信。给出卫星的数量和P个哨所的坐标,求D的最小值。

思路:

这道题主要要明白题意,本来就是个英文题,再加上有点儿绕,实在是在难为我这个英文小白,所以看懂英语真的很重要鸭。。。。

题上说一个卫星频道可以使两个哨所任意通信而忽略他们之间的距离,否则两个哨所之间只能通过电台进行通信,并且两个哨所之间的距离不能超过D,不然不在电台所能触及的范围之内就不能通信,距离D取决于电台的力量;给出卫星个数S,哨所个数P,以及每个哨所所在的坐标,问电台所需要的最小的距离D。

 S个卫星可以去掉S-1个哨所,所以最后只需要连接P-S+1各哨所就可以了,所以用Kruskal算法把所有边进行排序,最后输出第P-S条边的距离即电台所需要的最小的距离,就可以使剩下的哨所都能通过此电台通信。

(还有这道题在POJ上提交时如果你选的是G++提交,输出必须用%f,用%lf提交会答案错误,详细原因请点击这里

My  Code:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<math.h>
#include<set>
using namespace std;
#define INF 1e9
typedef long long ll;
int fa[505],n,cunt,m;
struct island
{
    double x,y;
}s[505];
struct Island
{
    int s,e;
    double dis;
}c[150000];
int cmp(Island c1,Island c2)
{
    return c1.dis < c2.dis;
}
int father(int x)
{
    if(x == fa[x]) return x;
    else
    {
        int root = father(fa[x]);
        fa[x] = root;
        return root;
    }
}
double Kruskal()
{
    for(int i = 1; i <= n; i++)
        fa[i] = i;
    sort(c,c+cunt,cmp);
    int ans = 0;
    double sum ;
    for(int i = 0; i < cunt; i++)
    {
        int a = father(c[i].s);
        int b = father(c[i].e);
        if(a != b)
        {
            ans++;
            fa[a] = b;
            if(ans == n-m)///输出第P-S条边
            {
                sum = c[i].dis;
                break;
            }
        }
    }
    return sum;
}
double distance(double x0,double y0,double x1,double y1)
{
    return sqrt((x0-x1)*(x0-x1)+(y0-y1)*(y0-y1));
}
int main()
{
    int t;
    cin >> t;
    while(t--)
    {
        scanf("%d%d",&m,&n);
        for(int i = 1; i <= n; i++)
            cin >> s[i].x >> s[i].y;
        cunt = 0;
        for(int i = 1; i < n; i++)
        {
            for(int j = i+1; j <= n; j++)
            {
                c[cunt].dis = distance(s[i].x,s[i].y,s[j].x,s[j].y);
                c[cunt].s = i;
                c[cunt].e = j;
                cunt++;
            }
        }
        double sum = Kruskal();
        printf("%.2f\n",sum);
    }

    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值