uva 10369 Arctic Network

最小生成树入门题

题意:有n个点给出坐标,点和点之间可以用无线电或者卫星通信,每个点都有无线电收发器可进行无线电通信,但是只有m个点有卫星通信功能。卫星通信的距离可以无限大,但无线电通信的距离不能超过D,超过D的部分将使通信费用增加。要使通信费用最少。

其实就是求一次最小生成树,m个点有卫星通信,那么就会有m-1条边的通信距离无限大,其实就是这m-1条边不用计算费用。而剩下的边中,找出最大边作为D值,这样剩下的所有的边都不会大于D,那么不会增加通信费用。在构建MST过程中保存下所有的边权值,然后按升序排序,除掉最后的m-1条边(也就是最大的m-1条边,这些边用卫星通信),最大的那条就是D

 

#include <cstdio>

#include <cstring>

#include <cmath>

#include <algorithm>

using namespace std;

#define N 510

#define INF 1000000000.000

double g[N][N];

int x[N],y[N];

int n,m;  //有m个卫星



double dis(int i ,int j)

{ return sqrt( 1.*(x[i]-x[j])*(x[i]-x[j])+1.*(y[i]-y[j])*(y[i]-y[j]) ); }





void prim()

{

    double lowcost[N],ans[N];

    int adj[N],cov[N];

    for(int i=2; i<=n; i++)

    {

        lowcost[i]=g[1][i];

        adj[i]=1;

        cov[i]=0;

    }

    lowcost[1]=0;  adj[1]=1; cov[1]=1;



    for(int nn=1; nn<n; nn++)  //还有纳入n-1个点

    {

        double min=INF;

        int k=1;

        for(int i=1; i<=n; i++) 

            if(!cov[i] && lowcost[i]<min)

            {

                min=lowcost[i];

                k=i;

            }

        //printf("%.2f\n",min);

        ans[nn]=min;

        cov[k]=1;



        for(int i=1; i<=n; i++)

            if(!cov[i] && lowcost[i] > g[k][i])

            {

                lowcost[i]=g[k][i];

                adj[i]=k;

            }

    }

    

    sort(ans+1 , ans+n);

/*

    for(int i=1; i<n; i++)

        printf("%.2f\n",ans[i]);

*/

    printf("%.2lf\n",ans[n-m]);

    return ;

}

int main()

{

    int T;

    scanf("%d",&T);

    while(T--)

    {

        scanf("%d%d",&m,&n);

        for(int i=1; i<=n; i++)

            scanf("%d%d",&x[i],&y[i]);



        for(int i=1; i<=n; i++) g[i][i]=0;



        for(int i=1; i<=n; i++)

            for(int j=i+1; j<=n; j++)

                g[i][j]=g[j][i]=dis(i,j);



        prim();

    }

    return 0;

}

 

你可能感兴趣的:(NetWork)