poj 2349 Arctic Network(最小生成树变形)

本文探讨了如何通过合理配置卫星通信和无线电通信来实现北极多个站点间的最经济有效的网络连接。提出了利用最小生成树算法确定最小通信成本的方法,并通过具体实例进行了解释。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Arctic Network
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 15862 Accepted: 5051

Description

The Department of National Defence (DND) wishes to connect several northern outposts by a wireless network. Two different communication technologies are to be used in establishing the network: every outpost will have a radio transceiver and some outposts will in addition have a satellite channel. 
Any two outposts with a satellite channel can communicate via the satellite, regardless of their location. Otherwise, two outposts can communicate by radio only if the distance between them does not exceed D, which depends of the power of the transceivers. Higher power yields higher D but costs more. Due to purchasing and maintenance considerations, the transceivers at the outposts must be identical; that is, the value of D is the same for every pair of outposts. 

Your job is to determine the minimum D required for the transceivers. There must be at least one communication path (direct or indirect) between every pair of outposts.

Input

The first line of input contains N, the number of test cases. The first line of each test case contains 1 <= S <= 100, the number of satellite channels, and S < P <= 500, the number of outposts. P lines follow, giving the (x,y) coordinates of each outpost in km (coordinates are integers between 0 and 10,000).

Output

For each case, output should consist of a single line giving the minimum D required to connect the network. Output should be specified to 2 decimal points.

Sample Input

1
2 4
0 100
0 300
0 600
150 750

Sample Output

212.13


题意:在北极有n个站点,现在有s个卫星系统,一个卫星系统可以设置在一个站点,有卫星的站点之间通信不需要耗费任何东西,如果两个站点之间有一个没有卫星,则需要花费两者的距离的花费D,现在问你,要做到所有站点都能互相通信,且所有花费D都相等(即取最大的那一个),D最小是多少?

思路:刚看到这道题,没什么思路。 度娘了一下也没怎么看懂,最后自己推了一下。

这道题一看就是求最小生成树,可是有s个卫星系统怎么处理呢?在0个或者1个卫星的情况下(1个无法起到作用,跟0个一样),这个题目就是求最小生成树,然后取最大的边。那么在一个卫星的基础上,我们每添加一个卫星,就相当于删除了两个村庄之间的一条边(由于卫星可以随便放置,所以我们可以假设两个卫星就在当前最大边的两个村庄),然后两个村庄合为一个村庄,由于我们要求最小的D,故我们要删除的肯定是当前最小生成树里最大的那一条边。以此类推,题目要求的其实是最小生成树里的第s大边。

这里有个疑问,比如当前s=3,最小生成树最长边与次长边的两边结点没有重合的,那么我们用两个卫星找到最长边的时候,是不是能用一个卫星就删除次长边呢? 答案是肯定的。

我们每一次加一个卫星,就是删除一条边,删除一条边,就是把最小生成树分割出一个分量(最小生成树是无环的,这个结论是显而易见的),那么,无论何时,当前的最长边所在的那一个连通分量,有且仅有一个卫星。我们只需要把那个卫星与当前最长边的其中一个结点连接,自然就能删除最长边了。 如果看不懂可以画个图看看,应该是很容易懂的。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define N 510
#define INF 100000000
int k,n;
struct Point
{
    double x,y;
} p[N];
double ma[N][N],ans[N],d[N];
int flag[N];
double dis(Point a,Point b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
bool cmp(double a,double b)
{
    return a>b;
}
void prim()
{
    for(int i=1; i<n; i++)
        d[i]=ma[0][i];
    flag[0]=1;
    for(int i=1; i<n; i++)
    {
        double maxn=INF;
        int v=-1;
        for(int j=1; j<n; j++)
            if(!flag[j]&&maxn>d[j])
            {
                maxn=d[j];
                v=j;
            }
        ans[i-1]=maxn;
        flag[v]=1;
        for(int j=1;j<n;j++)
            if(!flag[j]&&d[j]>ma[v][j])
                d[j]=ma[v][j];
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d %d",&k,&n);
        for(int i=0; i<n; i++)
            scanf("%lf %lf",&p[i].x,&p[i].y);
        for(int i=0; i<n; i++)
            for(int j=0; j<n; j++)
                ma[i][j]=dis(p[i],p[j]);
        memset(flag,0,sizeof(flag));
        prim();
        sort(ans,ans+n-1,cmp);
        if(k==0) k=1;
        printf("%.2lf\n",ans[k-1]);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值