北极通讯网络(最小生成树)

北极通讯网络

题意

北极的某区域共有n座村庄,每座村庄的坐标用一对整数 ( x , y ) (x,y) (x,y) 表示。为了加强联系,决定在村庄之间建立通讯网络。通讯工具可以是无线电收发机,也可以是卫星设备。所有的村庄都可以拥有一部无线电收发机,且所有的无线电收发机型号相同。但卫星设备数量有限,只能给一部分村庄配备卫星设备。
不同型号的无线电收发机有一个不同的参数 d d d,两座村庄之间的距离如果不超过 d d d 就可以用该型号的无线电收发机直接通讯, d d d 值越大的型号价格越贵。拥有卫星设备的两座村庄无论相距多远都可以直接通讯。
现在有 k k k台卫星设备,请你编一个程序,计算出应该如何分配这 k k k 台卫星设备,才能使所拥有的无线电收发机的 d d d 值最小,并保证每两座村庄之间都可以直接或间接地通讯。
例如,对于下面三座村庄:
Picture1其中 ∣ A B ∣ = 10 , ∣ B C ∣ = 20 , ∣ A C ∣ = 10 5 ≈ 22.36 ∣AB∣=10,∣BC∣=20,∣AC∣=10\sqrt{5}≈22.36 AB=10,BC=20,AC=105 22.36
如果没有任何卫星设备或只有 1 1 1台卫星设备( k = 0 k=0 k=0 k = 1 k=1 k=1),则满足条件的最小的 d = 20 d=20 d=20,因为 A A A B B B B B B C C C 可以用无线电直接通讯;而 A A A C C C 可以用 B B B 中转实现间接通讯(即消息从 A A A 传到 B B B,再从 B B B 传到 C C C );
如果有2台卫星设备( k = 2 k=2 k=2),则可以把这两台设备分别分配给 B B B C C C,这样最小的 d d d可取 10 10 10,因为 A A A和B之间可以用无线电直接通讯; B B B C C C之间可以用卫星直接通讯; A A A C C C可以用 B B B中转实现间接通讯。
如果有 3 3 3台卫星设备,则 A A A, B B B, C C C两两之间都可以直接用卫星通讯,最小的 d d d可取 0 0 0

思路

由题意可知, k k k 个卫星设备可以使得 k − 1 k - 1 k1 条通讯线路的 d d d 值变成 0 0 0,那么只需要将图中每个点之间的距离求出来,并求出最小生成树,然后去掉最小生成树中 k − 1 k - 1 k1条权值最大的边之后,剩下的边中权值最大的即为所求的 d d d

代码
// Author:zzqwtcc
// Problem: 北极通讯网络
// Contest: NowCoder
// Time:2021-10-20 19:59:44
// URL: https://ac.nowcoder.com/acm/contest/958/B
// Memory Limit: 65536 MB
// Time Limit: 2000 ms

#include<bits/stdc++.h>
#include<unordered_map>
// #define int long long
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3f
#define mod 1000000007
#define MOD 998244353
#define rep(i, st, ed) for (int (i) = (st); (i) <= (ed);++(i))
#define pre(i, ed, st) for (int (i) = (ed); (i) >= (st);--(i))
//#define debug(x,y) cerr << (x) << " == " << (y) << endl;
#define endl '\n'
using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
template<typename T> inline T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }
template<typename T> inline T lowbit(T x) { return x & -x; }
template<typename T,typename S>inline void debug(S s,T t){cerr << s << " " << t << endl;}
template<typename T>inline void debug(T t){cerr << t << endl;}
// template<typename T> T qmi(T a, T b = mod - 2, T p = mod) { T res = 1; b %= (p - 1 == 0 ? p : p - 1); while (b) { if (b & 1) { res = (LL)res * a % p; }b >>= 1; a = (LL)a * a % p; }return res % mod; }

const int N = 600;
int n, k;
struct Node{
	double x,y;
}node[N];

double dist[N][N];
bool vis[N];
double d[N];
vector<double>vec;

double get_dis(const Node &a,const Node &b){
	return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}

void prim(){
	rep(i,1,n)d[i] = DBL_MAX;
	d[1] = 0;
	int cnt = 0;
	for(int i = 1; i <= n;++i){
		int t = -1;
		for(int j = 1; j <= n;++j){
			if(!vis[j] && (t == - 1 || d[t] > d[j]))t = j;
		}
		vec.push_back(d[t]);
		vis[t] = true;
		
		for(int j = 1; j <= n;++j){
			d[j] = min(d[j], dist[t][j]);
		}
	}
}

void solve() {
    cin >> n >> k;
    for(int i = 1; i <= n;++i){
    	cin >> node[i].x >> node[i].y;
    }
    
    for(int i = 1; i <= n;++i){
    	for(int j = i + 1; j <= n;++j){
    		double dis = get_dis(node[i],node[j]);
    		dist[i][j] = dist[j][i] = dis;
    	}
    }
    
    prim();
    sort(vec.begin(),vec.end());
    reverse(vec.begin(),vec.end());
    
    if(k <= 1){
    	printf("%.2lf\n",vec[0]);
    }
    else if(k < n){
    	printf("%.2lf\n",vec[k - 1]);
    }
    else cout << 0 << endl;
}

signed main() {

    //int _; cin >> _;
    //while (_--)
        solve();

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zzqwtc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值