1. 程式人生 > >POJ 2349 Arctic Network(最小生成樹+第K大的邊)

POJ 2349 Arctic Network(最小生成樹+第K大的邊)

題意:有S顆衛星和P個哨所,有衛星的兩個哨所之間可以任意通訊;否則,一個哨所只能和距離它小於等於D的哨所通訊。給出衛星的數量和P個哨所的座標,求D的最小值。

思路:因為題目要求每兩個點都能通訊,所以可以轉化成最小生成樹,然後記錄每次加進去的邊,最後對這個陣列排一下序,因為s個衛星能連s-1條邊,所以取rec[p-2-(s-1)]即rec[p-s-1]就是滿足條件的D。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
#include<iomanip>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const int maxn=505;
const double eps=1e-8;
const double PI = acos(-1.0);
ll gcd(ll a,ll b)
{
    return b==0?a:gcd(b,a%b);
}
bool vis[maxn];
double lowc[maxn],rec[maxn];
double prim(double cost[][maxn],int n)
{
    int ans=0;
    memset(vis,false,sizeof(vis));
    memset(rec,0,sizeof(rec));
    vis[0]=true;
    for(int i=1; i<n; i++)
    {
        lowc[i]=cost[0][i];
    }
    for(int i=0; i<n-1; i++)
    {
        double minc=inf;
        int p=-1;
        for(int j=0; j<n; j++)
        {
            if(!vis[j]&&minc>lowc[j])
            {
                minc=lowc[j];
                p=j;
            }
        }
        if(minc==inf)   return -1;
        ans+=minc;
        rec[i]=minc;
        vis[p]=true;
        for(int j=0; j<n; j++)
        {
            if(!vis[j]&&lowc[j]>cost[p][j])
                lowc[j]=cost[p][j];
        }
    }
    return ans;
}
struct node
{
    double x,y;
};
double dis(node a,node b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    int t;
    cin>>t;
    while(t--)
    {
        node a[maxn];
        int s,p;
        double g[maxn][maxn];
        cin>>s>>p;
        for(int i=0;i<p;++i)
        {
            cin>>a[i].x>>a[i].y;
        }
        for(int i=0;i<p;i++)
        {
            for(int j=i+1;j<p;j++)
            {
                g[i][j]=g[j][i]=dis(a[i],a[j]);
            }
        }
        prim(g,p);
        sort(rec,rec+p-1);
      //  cout<<p-s-1<<endl;
        printf("%.2lf\n",rec[p-s-1]);
    }
    return 0;
}