首页 > 其他 > 详细

【洛谷P1991】无线通讯网

时间:2019-01-04 22:56:20      阅读:186      评论:0      收藏:0      [点我收藏+]

题目大意:给定一个 N 个顶点的完全图,边有边权,现在要求使得图中所有顶点联通的情况下,第 M-1 大的边最小值是多少。

题解:所有点联通的最小要求是所有点和连接这些点的边构成原图的一棵生成树,那么问题转化成原图的一棵生成树中第 M-1 大边的最小值是多少。可知这是一道类似最小瓶颈树的题目,即:最小生成树的第 M-1 大边一定是所有生成树中最小的。因此,答案转化成原图最小生成树中第 M-1 大边。

代码如下

#include <bits/stdc++.h>
using namespace std;
const int maxn=510;
const int maxx=3e5+10;

double x[maxn],y[maxn],rec[maxn];
int n,m,tot,cnt,f[maxn];
struct edge{
    int from,to;
    double w;
}e[maxx];
bool cmp(const edge& a,const edge& b){return a.w<b.w;}

inline double get_dis(int i,int j){
    return sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
}

int find(int x){
    return x==f[x]?x:f[x]=find(f[x]);
}

void read_and_parse(){
    scanf("%d%d",&m,&n);
    for(int i=1;i<=n;i++)scanf("%lf%lf",&x[i],&y[i]),f[i]=i;
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)
            e[++tot].w=get_dis(i,j),e[tot].from=i,e[tot].to=j;
}

void solve(){
    sort(e+1,e+tot+1,cmp);
    for(int i=1;i<=tot;i++){
        int a=find(e[i].from),b=find(e[i].to);
        if(a!=b)rec[++cnt]=e[i].w,f[a]=b;
    }
    printf("%.2lf\n",rec[cnt-m+1]);
}

int main(){
    read_and_parse();
    solve();
    return 0;
}

【洛谷P1991】无线通讯网

原文:https://www.cnblogs.com/wzj-xhjbk/p/10222903.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!