b_lg_无线通讯网 & 北极通讯网络(问题转化+kruskal)

无线通讯网

每个边防哨所都要配备无线电收发器;有一些哨所还可以增配卫星电话(无线电话的通信距离为无限长)。
每一对哨所之间的通话距离都是同一个D,给定n个哨站和m个收发器,
你的任务是确定收发器必须的最小通话距离D,使得每一对哨所之间至少有一条通话路径(直接的或者间接的)

思路
贪心:n个无线电安排在边权最大的点上;然后让剩下的m-n个哨站安装收发器;
kruskal取前m-n(m-1-(s-1),m-1条减去无线电话省去的s-1条)条边中的最大者(因为要保证m-n条边中任意两条满足两点通信)

#include<bits/stdc++.h>
using namespace std;
const int N=505;
int n,m,fa[N];
struct node {
    double x,y,w;
}a[N*N], e[N*N];
int find(int u) {
    return fa[u]==u ? u : fa[u]=find(fa[u]);
}
double getDist(node& a, node& b) {
    return sqrt(((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y)));
}
int main() {
    std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cin>>n>>m; for (int i=0; i<m; i++) cin>>a[i].x>>a[i].y, fa[i]=i;
    int c=0;
    for (int i=0; i<m; i++)
    for (int j=0; j<i; j++) {
        e[c].x=i, e[c].y=j, e[c++].w=getDist(a[i], a[j]);
    }
    sort(e, e+c, [&](node a, node b) {return a.w<b.w;});
    double ans=0x3f3f3f3f;
    for (int i=0, t=m-n; i<c && t; i++) {
        int fx=find(e[i].x), fy=find(e[i].y);
        if (fx!=fy) {
            fa[fx]=fy;
            ans=e[i].w, t--;
        }
    }
    printf("%.2lf", ans);
    return 0;
}

北极通讯网络

共有n座村庄,k台卫星设备,无线电收发机有一个不同的参数d,d越大价格越贵,计算出应该如何分配这 k 台卫星设备,才能使所拥有的无线电收发机的d值最小

思路:一开始有n个连通块,肯定是将边权最小的村庄用收发器连接,最后用k个卫星设备将k个连通块连接起来

#include<bits/stdc++.h>
using namespace std;
const int N=505;
int n,k,m,fa[N];
struct edge {
    int u,v;
    double w;
}E[N*N];
struct node {
    int x,y;
}A[N];
double getDist(node& a, node& b) {
    int dx=a.x-b.x, dy=a.y-b.y;
    return sqrt(dx*dx+dy*dy);
}
int find(int u) {return fa[u]==u ? u : fa[u]=find(fa[u]);}
double kruskal() {
    for (int i=0; i<n; i++) fa[i]=i;
    sort(E,E+m,[&](edge a, edge b) {return a.w<b.w;});
    double d=0;
    int c=n;
    for (int i=0; i<m && c>k; i++) {
        int fu=find(E[i].u), fv=find(E[i].v);
        if (fu!=fv) {
            fa[fu]=fv, d=E[i].w;
            c--;
        }
    }
    return d;
}
int main() {
    std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cin>>n>>k;
    for (int i=0; i<n; i++) cin>>A[i].x>>A[i].y;
    for (int i=0; i<n; i++)
    for (int j=0; j<i; j++) {
        E[m++]={i,j,getDist(A[i], A[j])};
    }
    printf("%.2lf", kruskal());
    return 0;
}
posted @ 2020-10-10 22:31  童年の波鞋  阅读(124)  评论(0编辑  收藏  举报