Arctic Network北极网络
目录
The Department of National Defence (DND) wishes to connect several northern outposts by a wireless network. Two different communication technologies are to be used in establishing the network: every outpost will have a radio transceiver and some outposts will in addition have a satellite channel.
Any two outposts with a satellite channel can communicate via the satellite, regardless of their location. Otherwise, two outposts can communicate by radio only if the distance between them does not exceed D, which depends of the power of the transceivers. Higher power yields higher D but costs more. Due to purchasing and maintenance considerations, the transceivers at the outposts must be identical; that is, the value of D is the same for every pair of outposts.
Your job is to determine the minimum D required for the transceivers. There must be at least one communication path (direct or indirect) between every pair of outposts.
Input
The first line of input contains N, the number of test cases. The first line of each test case contains 1 <= S <= 100, the number of satellite channels, and S < P <= 500, the number of outposts. P lines follow, giving the (x,y) coordinates of each outpost in km (coordinates are integers between 0 and 10,000).
Output
For each case, output should consist of a single line giving the minimum D required to connect the network. Output should be specified to 2 decimal points.
任何两个有卫星频道的哨站都可以通过卫星进行通信,无论它们位于何处。否则,两个哨站只有在它们之间的距离不超过 D 时才能通过无线电通信,这取决于收发器的功率。更高的功率产生更高的 D,但成本更高。出于采购和维护的考虑,前哨的收发器必须相同;也就是说,每对前哨站的 D 值都相同。
您的工作是确定收发器所需的最小 D。每对前哨站之间必须至少有一条通信路径(直接或间接)。
输入
输出
Sample Input
1 2 4 0 100 0 300 0 600 150 750
Sample Output
212.13
题意描述:
给你多组数据,第一行是卫星频道数何前哨战数,根据题目要求,把卫星频道给距离相差很远的前哨,然后求剩下没有卫星频道的相距最远的前哨间距离
Kruskal算法解题思路:
用了kruskal,写两个for循环来求给的点之间的距离,然后把距离进行排序,最后输出除了放卫星排序最大的距离。
易错分析:
题目要求的是小数,所以我们在计算距离和在单独写kruskal函数的时候注意定义成define 然后就是多实例问题,注意初始化数据的时候位置不要放错
当然如果这个数据特别大的话,可能会时间超限,这种题还是比较适合prim (下面有。)
Kruskal AC代码
#include<stdio.h> #include<algorithm> #include<math.h> using namespace std; int m,n,cnt,fa[550]; struct Node { int a,b; double d;// }p[250020]; void init()//并查集初始化 { int i; for(int i=1;i<=550;i++) { fa[i]=i; } } int cmp(Node x, Node y) { return x.d<y.d;//结构体从小到大排序 } int find(int x)//寻找祖先 { if(x==fa[x]) return x; else return fa[x]=find(fa[x]); } double kruskal()//这里也要用double !!! { int rec=0; sort(p,p+cnt,cmp);// !!!! double ans=0;// for(int i=1;i<cnt;i++)// { if(rec==m-n) break;//直到选用了n-1条边之后退出循环 int x=find(p[i].a),y=find(p[i].b); if(x!=y) { fa[x]=y; ans=p[i].d; rec++; } } return ans; } int main(void) { int t; // cnt=1;放while循环里面 double x[550],y[550];//因为下面求的是double 所以也要用double !!!!! scanf("%d",&t); while(t--) { cnt=1; scanf("%d %d",&n,&m);//n代表卫星数,m表有多少个前哨站 init();//初始化 for(int i=1;i<=m;i++) { scanf("%lf %lf",&x[i],&y[i]);//注意书写格式 } double a; for(int i=1;i<=m;i++) { for(int j=i+1;j<=m;j++) { // a=sqrt((x[i]-x[j])*((x[i]-x[j]))+(y[i]-y[j])*(y[i]-y[j])); p[cnt].a=i;//简写成1,2 p[cnt].b=j;// p[cnt].d=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])); cnt++; //printf("%.2f\n",a); } } printf("%.2f\n",kruskal()); } return 0; }
Prim解题思路:
因为有坐标,所以我们把前一个点和后一个点的距离存入二维数组,然后利用prim算法 可以为我们求得所有点通过的最短路,因为我们要求的是除了有卫星频道是最长的边之外,其它最长的一条边的长度,所以我们要把所有的值进行排序,然后输出那个值
易错分析:
因为我是从1开始定义的,所以排序的时候sort(dis,dis+卫星数+1)输出也是dis[n-m+1],感兴趣的可以看下我下面排序的代码,那两个for循环,自己输入题目给的数据,会发现sort按0开始,但是如果定义1开头的话,就要再加1
Prim AC代码
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#define N 1050
using namespace std;
int n,m,book[N];
double e[N][N],dis[N];
double inf=9999999.0;
void Prim()
{
double min;
int u;
for(int i=1;i<=n;i++)
{
dis[i]=e[1][i];
book[i]=0;
}
//dis[1]=0;
book[1]=1;
for(int i=1;i<n;i++)
{
min=inf;
for(int j=1;j<=n;j++)
{
if(book[j]==0&&dis[j]<min)
{
min=dis[j];
u=j;
}
}
book[u]=1;
for(int k=1;k<=n;k++)
{
if(book[k]==0&&dis[k]>e[u][k])
{
dis[k]=e[u][k];
}
}
}
// for(int i=1;i<=n;i++) 就是这两个for循环!!!!🤐
// {
// printf("%.2f\n",dis[i]);
// }
sort(dis,dis+n+1);//
// for(int i=1;i<=n;i++)
// {
// printf("%.2f\n",dis[i]);
// }
printf("%.2f\n",dis[n-m+1]);//
}
int main(void)
{
int t;
double x[N],y[N];
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&m,&n);
//读入边
for(int i=1;i<=n;i++)
{
scanf("%lf %lf",&x[i],&y[i]);
for(int j=1;j<=n;j++)
{
e[i][j]=e[j][i]=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
}
}
Prim();
}
return 0;
}