POJ - 2349 Arctic Network
https://vjudge.net/problem/POJ-2349
用kruskal,因为允许间接通讯,边权值也是升序排列的,那么去掉前k个大的边,剩下的就是满足通讯至少需要的强度(这个强度说的是两个最远的点之间的,可能小于总的最小连通值,但是允许间接通信)
用prim做的话先得到完整的dis数组,然后给它排序后边的k个用卫星通讯,倒数第k+1个就是至少需要的强度
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int N=500,M=N*N/2;
int n,m,T,k;
int p[M];
int find(int x)
{
if(p[x]!=x) p[x]=find(p[x]);
return p[x];
}
struct node{
double x,y;
}e[M];
struct edge{
int u,v;
double w;
}g[M];
double getd(int i,int j)
{
double x=e[i].x-e[j].x;
double y=e[i].y-e[j].y;
return sqrt(x*x+y*y);
}
bool cmp(struct edge ww,struct edge uu)
{
return ww.w<uu.w;
}
double kruskal()
{
for(int i=1;i<=m;i++) p[i]=i;
// cout<<k<<endl;
sort(g,g+k,cmp);
double ans=0;
int cnt=m;
for(int i=0;i<k;i++)
{
if(cnt<=n) break; //边值是升序排过序的 ,把最后n个留下直接用卫星信道通讯,那么第n+1大的就是信号强度最低值,这样才能覆盖全场
//因为允许间接通讯,因此只要通讯器能达到 第n+1大的值即可
int a=find(g[i].u),b=find(g[i].v);
if(a!=b)
{
p[a]=b;
ans=g[i].w;
cnt--;
}
}
return ans;
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++)
scanf("%lf %lf",&e[i].x,&e[i].y);
k=0;
for(int i=1;i<m;i++)
{
for(int j=i+1;j<=m;j++)
{
double d=getd(i,j);
g[k].u=i;
g[k].v=j;
g[k].w=d;
k++;
}
}
printf("%.2f\n",kruskal());
}
return 0;
}
本文来自博客园,作者:斯文~,转载请注明原文链接:https://www.cnblogs.com/zhiweb/p/15483303.html

浙公网安备 33010602011771号