【洛谷】P1991 无线通讯网

看一眼,这不就是赤裸裸的最小生成树模板吗?

也许你会问:"s是干嘛的?"

我来告诉你——s!没用!

之前我们做最小生成树的模板时,是不是有n - 1条边就可以退出了,这里其它的没变,就退出条件变了。这里s可能排上一点点用场了,退出条件变成了p - s(p和之前的n是几乎一样的)。

既然是最小生成树的模板题,那必然会有两大经典算法——KruskalPrim

!!!:***p-s:用p个卫星电话把最后(距离最远)s个代替了(sort过的e[i].w)

ACcode:(kruskal)

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=250010;//!!!任意(不包括本身自己跟自己)两点都可以组成一个数据
struct node{
    int x,y;
}a[N];

struct edge{
    int u,v;
     double w;
}e[N];

int fa[N];

int s,p,idx,cnt;
double sum;

bool cmp(edge a,edge b)//kruskal模板标配
{
    return a.w<b.w;
}
int find(int x)//并查集,//kruskal模板标配
{
    if(fa[x]==x)return x;
    else
    {
        fa[x]=find(fa[x]);
        return fa[x];
    }
}
void kruskal()kruskal模板标配
{
    for(int i=1;i<=idx;i++)
    {
        int f1=find(e[i].u);
        int f2=find(e[i].v);
        if(f1!=f2)
        {
            sum=e[i].w;//唯一不同点,记录
            cnt++;
            fa[f1]=f2;
        }
        if(cnt>=p-s)break;//***p-s,用p个卫星电话把最后(距离最远)s个代替
            }
}
int main()
{
    cin>>s>>p;
    for(int i=1;i<=p;i++)
    {
        cin>>a[i].x>>a[i].y;//输入 
    }
    for(int i=1;i<=p;i++){
        fa[i]=i;//初始化父节点 
    }
    for(int i=1;i<=p;i++)//把边储存起来
    for(int j=i+1;j<=p;j++)
    {
        double z=sqrt((double)(a[i].x-a[j].x)*(a[i].x-a[j].x)+(double)(a[i].y-a[j].y)*(a[i].y-a[j].y));//距离 
        e[++idx].u=i;//idx标记一共有多少条边 
        e[idx].v=j;
        e[idx].w=z; 
     } 
     sort(e+1,e+1+idx,cmp);
     kruskal();
     printf("%.2lf",sum);
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值