POJ2349,ZOJ1914,Arctic Network

题意就不解释了,需要注意的是,每个卫星频道对应的是一个点,不是一条边!

首先跑完prim之后,会得到一个数组d,里面保存的是最小生成树的每条边

然后有s个卫星频道,那么就有s-1条边,所以直接在d数组里取第s条边就行了(之前得将d数组从大到小排下序)

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<climits>
#include<cmath>
#include<algorithm>
using namespace std;
int t,s,p;
double maz[509][509];//存图
double d[509];//跑prim时用的数组
bool vis[509];//标记数组
double dis(int a[],int b[])
{
    double x,y,sum;
    x = (a[0]-b[0]) * (a[0]-b[0]);
    y = (a[1]-b[1]) * (a[1]-b[1]);
    sum = sqrt((x+y)*1.0);
    return sum;
}//得到两点之间的距离
bool cmp(int a,int b)
{
    return a > b;
}//使数组元素从大到小排序
void prim()//基本就是模板,只不过这次目的是得到那个d数组,而不是最后结果
{
    int i,j,pos,cnt;
    double t;
    memset(d,false,sizeof(d));
    for (i = 1; i <= p; ++i)
        d[i] = maz[1][i];
    memset(vis,false,sizeof(vis));
    vis[1] = true;
    for (i = 0; i < p-1; ++i)
    {
        t = INT_MAX;
        for (j = 1; j <= p; ++j)
        {
            if (!vis[j] && t > d[j])
            {
                t = d[j];
                pos = j;
            }
        }
        vis[pos] = true;
        for (j = 1; j <= p; ++j)
        {
            if (!vis[j] && d[j] > maz[pos][j])
            {
                d[j] = maz[pos][j];
            }
        }
    }
    sort(d+1,d+1+p,cmp);//把数组元素从大到小排序,数组是从1开始的,不是0
    cnt = s - 1;
    printf("%.2lf\n",d[1+cnt]);//取滴s条边
}
int main()
{
    int i,j;
    int pi[509][2];
    double tem;
    while (~scanf("%d",&t))
    {
        while (t--)
        {
            scanf("%d%d",&s,&p);
            for (i = 1; i <= p; ++i)
            {
                scanf("%d%d",&pi[i][0],&pi[i][1]);
            }//保存原始数据
            for (i = 1; i <= p; ++i)
            {
                for (j = 1; j <= p; ++j)
                {
                    maz[i][j] = i == j ? 0 : INT_MAX;
                }
            }//初始化maz数组
            for (i = 1; i <= p; ++i)
            {
                for (j = i+1; j <= p; ++j)
                {
                    tem = dis(pi[i],pi[j]);
                    maz[i][j] = maz[j][i] = tem;
                }
            }//存图
            prim();
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值