UVA 10369 Arctic Network

 

 


题目大意:
南极有n个科研站, 要把这些站用卫星或者无线电连接起来,使得任意两个都能直接或者间接相连。任意两个都有安装卫星设备的,都可以直接通过卫星通信,不管它们距离有多远。 而安装有无线电设备的两个站,距离不能超过D。 D越长费用越多。
现在有s个卫星设备可以安装,还有足够多的无线电设备,求一个方案,使得费用D最少(D取决与所有用无线电通信的花费最大的那条路径)。

分析与总结:
很自然的想到求最小生成树,然后为了使得D费用最少,就要让其中路径最长的那些用来安装卫星。 s个通信卫星可以安装s-1条最长的那些路径。 那么, 最小生成树中第p-s大的路径长度就是D。
只需要求出最小生成树上的所有路径长度,排好序,边得到答案。

CODE:

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <queue>
using  namespace std;

#define MAXN 1100
#define INF 0X3F3F3F3F

int n, k, m;

struct node
{
     double x, y;
}a[MAXN*MAXN];

struct Edge
{
     int u, v;
     double w;
}edge[MAXN*MAXN];

int p[MAXN], tot;

int cmp( const Edge a,  const Edge b)
{
     return a.w < b.w;
}

double w[MAXN][MAXN], d[MAXN];

void init()
{
    tot =  0;
}

double dist( const node a,  const node b)
{
     return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
}

int find( int x)

     return x == p[x]? x : p[x] = find(p[x]);
}

void Kruskal()
{
     double ans =  0;
     int count =  0;
     for( int i =  0; i <= n; i++) p[i] = i;
    sort(edge, edge+tot, cmp);
     for( int i =  0; i < tot; i++)
    {
         int x = find(edge[i].u), y = find(edge[i].v);
         if(x != y)
        {
            ans = edge[i].w;
            p[x] = y;
            count++;
        }
         if(count == n-m)
        {
            printf( " %.2lf\n ", ans);
             return ;
        }
    }
}

int main()
{
     int T;
    scanf( " %d ", &T);
     while(T--)
    {
        init();
        scanf( " %d%d ", &m, &n);
         for( int i =  1; i <= n; i++) scanf( " %lf%lf ", &a[i].x, &a[i].y);
         for( int i =  1; i <= n; i++)
        {
             for( int j =  1; j <= n; j++)  if(i != j)
            {
                edge[tot].u = i, edge[tot].v = j;
                edge[tot].w = dist(a[i], a[j]);
                tot++;
            }
        }
        Kruskal();
    }
     return  0;
}

 

你可能感兴趣的:(NetWork)