POJ2349

#include<iostream>//POJ2349
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define inf (0x3f3f3f3f)
#define DEF (1e-5)
using namespace std;
const int maxn = 500 + 5;
/*一些最小生成树的新见解
(因为最小生成树是贪心构造,
每一条边都是体系内的最短距
离,所以也可以用来求构造一
幅图的的最长需要的边)*/
bool cmp(const double& a,const double& b)
{
    return a > b;
}
typedef struct
{
    int x,y;
}node;
double Grape[maxn][maxn];//u - v节点边的权值
int N,S,P;//S为卫星的数量,P为哨号的个数
node nodeArr[maxn];
bool vis[maxn];
double d[maxn];
int p[maxn];
double arr[maxn];
void Prim()
{
    memset(p,-1,sizeof(p));
    memset(vis,false,sizeof(vis));
    memset(arr,0,sizeof(arr));
    for(int i=0;i!=P;++i)
        d[i] = 1<<21;//相当于inf
    d[0] = 0;
    while(true)
    {
        double mincost = 1<<21;
        int u;
        for(int i=0;i!=P;++i)
        {
            if(!vis[i]&&d[i]<mincost)
            {
                mincost = d[i];
                u = i;
            }
        }
        //cout<<mincost-(1<<21)<<endl;
        if(fabs(mincost-(1<<21))<DEF)
            break;
        vis[u] = true;
        for(int v=0;v!=P;++v)
        {
            if(!vis[v]&&d[v]>Grape[u][v])
            {
                d[v] = Grape[u][v];
                p[v] = u;
            }
        }
    }
    int index = 0;
    for(int i=0;i!=P;++i)
        if(p[i]!=-1)
            arr[index++] = Grape[i][p[i]];
    sort(arr,arr+index,cmp);
    printf("%.2lf
",arr[S-1]);//应为S个节点构成s-1条道路
}
int main()
{
    cin>>N;
    while(N--)
    {
        cin>>S>>P;
        for(int i=0;i!=P;++i)
            cin>>nodeArr[i].x>>nodeArr[i].y;
        memset(Grape,0,sizeof(Grape));
        //构建图
        for(int i=0;i<=P-1;++i)
        {
            double len = 0;
            for(int j=i+1;j<=P-1;++j)
            {
                len = sqrt(double((nodeArr[i].x-nodeArr[j].x)*(nodeArr[i].x-nodeArr[j].x)+(nodeArr[i].y-nodeArr[j].y)*(nodeArr[i].y-nodeArr[j].y)));
                Grape[i][j] = Grape[j][i] = len;
            }
        }
        // for(int i=0;i!=P;++i)
        // {
        //     for(int j=0;j!=P;++j)
        //         cout<<Grape[i][j]<<" ";
        //     cout<<endl;
        // }
        Prim();
    }
}
不怕万人阻挡,只怕自己投降。
原文地址:https://www.cnblogs.com/newstartCY/p/11553306.html