poj入门水题---2349prime算法生成最小生成树

题目链接:http://poj.org/problem?id=2349


最小生成树:

连通一些点,要求边之和最小。


prime 算法

1.选取一个点(一般我就取第一个了,反正最后都是要加入最小生成树中的= =),标记为遍历过。

2.初始化距离数组,值为和1中选取的点的距离。

3.在未遍历的点中,找出与集合中的点距离最近的点x,标记为遍历过。

4.用x跟新距离,即,若集合中未遍历过的点a所对应的距离比其和x的距离小的话,用a和x的距离替代原先a所对应的距离。

重复3,4至所有点遍历过(共n-1次遍历)。


题目意思:

有m个基站,互相之间可以用无线电联系,这m个基站中,有s个基站配备了卫星接收装置,这意味着他们之间也可以用卫星联系。

因为无线电要覆盖的距离越远,需要的价格就越贵,现在需要求解无线电之间最小的距离D,使得所有基站之间都可以联系。


思路:

1.所有基站之间都能联系,求最小距离:即求最小生成树

2.有s个基站可以通过卫星联系,即可以产生s-1条边,要使D最小,那么这s-1条边一定是最小生成树中最大的s-1条边。

所以在生成最小生成树之后,排个序,输出第s大的边即可。


代码如下:

#include<iostream>
#include<math.h>
#include<algorithm>
#define N 505
#define inf 9999999
using namespace std;

bool vis[N];
double low[N],map[N][N];
int n;

struct ori
{
       int x,y;
}a[N];

void prime()
{
       int i,j,pos;
       double min,sum=0,tmp;
       memset(vis,0,sizeof(vis));
       pos=0;
       vis[0]=1;
       for(i=0;i<n;i++)
       low[i]=(a[0].x-a[i].x)*(a[0].x-a[i].x)+(a[0].y-a[i].y)*(a[0].y-a[i].y);
       for(i=0;i<n-1;i++)
       {
                         min=inf;
                         for(j=0;j<n;j++)
                         if(j!=pos)
                         if(!vis[j]&&low[j]<min)
                         {
                                                min=low[j];
                                                pos=j;
                         }
                         vis[pos]=1;
                         for(j=0;j<n;j++)
                         if(!vis[j])
                         {
                                tmp=(a[pos].x-a[j].x)*(a[pos].x-a[j].x)+(a[pos].y-a[j].y)*(a[pos].y-a[j].y);
                                if(low[j]>tmp)
                                low[j]=tmp;
                         }
       }
}
                                                
       
int main()
{
    int t,s,i;
    scanf("%d",&t);
    while(t--)
    {
              scanf("%d%d",&s,&n);
              for(i=0;i<n;i++)
              scanf("%d%d",&a[i].x,&a[i].y);
              prime();
              sort(low,low+n);
              printf("%.2lf\n",sqrt(low[n-s]));
    }
    return 0;
}

很久之前写的代码,最大值还用999999。。。

后来就用0xFFFF了,

但其实因为int在不同的机器上的长度不同,应该使用unsigned(-1)>>1来表示最大值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值