题干:

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.

Sample Input

1
2 4
0 100
0 300
0 600
150 750

Sample Output

212.13

题目大意:

南极有n个科研站, 要把这些站用卫星或者无线电连接起来,使得任意两个都能直接或者间接相连。任意两个都有安装卫星设备的,都可以直接通过卫星通信,不管它们距离有多远。 而安装有无线电设备的两个站,距离不能超过D。 D越长费用越多。

现在有s个卫星设备可以安装,还有足够多的无线电设备,求一个方案,使得费用D最少(D取决与所有用无线电通信的花费最大的那条路径)。

题意:有n个点给出坐标,点和点之间可以用无线电或者卫星通信,每个点都有无线电收发器可进行无线电通信,但是只有m个点有卫星通信功能。卫星通信的距离可以无限大,但无线电通信的距离不能超过D,超过D的部分将使通信费用增加。要使通信费用最少。

其实就是求一次最小生成树,m个点有卫星通信,那么就会有m-1条边的通信距离无限大,其实就是这m-1条边不用计算费用。而剩下的边中,找出最大边作为D值,这样剩下的所有的边都不会大于D,那么不会增加通信费用。在构建MST过程中保存下所有的边权值,然后按升序排序,除掉最后的m-1条边(也就是最大的m-1条边,这些边用卫星通信),最大的那条就是D;

解题报告:

注意题目中  有s个卫星,也就是说可以连s-1条边!所以最后答案还要+1

ac代码:(329ms  2.2MB)(用m==n-1跳出循环也才313ms)(用double然后算dist的时候就用sqrt也不算慢,,344ms)

#include<iostream>
#include<cmath>
#include<cstdio>
#include<algorithm>
const int MAX = 500 + 5;using namespace std;
int s,p;
int top;
long long ans[1000];
int f[MAX];
struct Node {int x,y;
} node[MAX];
struct Edge {int u,v;//别写x,y、其实更准确说应该是u和v,因为这时候你存的是两个点。你如果用x和y代表一个点的话,那就需要用x1x2y1y2来表示Edge结构体了 long long w;//权值 在此处就是距离
//  Edge(int u,int v,long long w) : u(u),v(v),w(w) {}
}edge[MAX * MAX + 5];
bool cmp(const Edge & a,const Edge & b) {return a.w<b.w;}
int getf(int v) {return f[v] == v ? v : f[v] = getf(f[v] );
}
void merge(int u, int v) {int t1 = getf(u );int t2 = getf(v );if(t1 != t2) {f[t2] =t1;}
}
int main()
{int t;cin>>t;long long dist;while(t--) {//留给初始化 top = 0;for(int i = 0; i<MAX; i++) {f[i]=i;}scanf("%d %d",&s,&p);//有 p 个点, 即p就是以前的n for(int i= 0; i<p;i++) {//从0开始读的! scanf("%d %d",&node[i].x,&node[i].y); }for(int i = 0; i<p; i++) {for(int j = i+1; j<p; j++) {top++;dist = (node[i].x-node[j].x )*(node[i].x-node[j].x ) + (node[i].y-node[j].y )*(node[i].y-node[j].y );//edge[top] = (i,j,dist);
//              printf("****%lld\n",dist);edge[top].u=i;edge[top].v=j;edge[top].w=dist; }}int cur=0;sort(edge + 1,edge+top +1,cmp);for(int i = 1; i<=top; i++) {if(getf(edge[i].u) != getf(edge[i].v ) ) {merge(edge[i].u ,edge[i].v );++cur;ans[cur] = edge[i].w;}}
//      printf("cur = %d\n",cur);
//      for(int i = 1; i<=cur; i++) {
//          printf("%lld  ",ans[i]);
//      }printf("%.2f\n",sqrt(ans[cur-(s - 1) ] * 1.0) );}return 0 ;} 

AC代码2:(prim算法)(32ms,2.1MB)

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define N 505
using namespace std;
double x[N], y[N], w[N][N], key[N], ans[N*N];
int n,m,pre[N],hash[N]; inline double getDist(double x1,double y1,double x2,double y2){return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}double Prim(){memset(hash, 0, sizeof(hash));hash[1] = 1;for(int i=1; i<=n; ++i){key[i] = w[1][i]; pre[i] = 1;}int k=0;for(int i=1; i<n; ++i){int u=-1;for(int j=1; j<=n; ++j)if(!hash[j]){if(u==-1 || key[j]<key[u]) u=j;}ans[k++] = key[u];hash[u] = 1;for(int j=1; j<=n; ++j)if(!hash[j]&&key[j]>w[u][j]){key[j]=w[u][j]; pre[j]=u;}}sort(ans, ans+k);return ans[k-m];
}int main(){int T;scanf("%d",&T);while(T--){scanf("%d%d",&m,&n);for(int i=1; i<=n; ++i)scanf("%lf%lf",&x[i],&y[i]);int pos=0;memset(w, 0, sizeof(w));for(int i=1; i<=n; ++i){for(int j=i+1; j<=n; ++j){w[i][j]=w[j][i]=getDist(x[i],y[i],x[j],y[j]);}} printf("%.2f\n", Prim());}return 0;
}

总结:

注意该用top的地方用top,该ij的地方ij,该uv的地方uv!!for(int i = 1; i<=top; i++) {   a[top] = ...  }这种错别再犯啦!是n的时候还好,就怕这种i<top啊 i<u啊i<v  里面getf(i)就顺手写成getf(v)了。

【POJ - 2349】【UVA - 10369】 Arctic Network(最小生成树求权值第k大的边)(内附两种算法)相关推荐

  1. 带你辨析最小生成树的两种算法

    最小生成树的算法通常由在几个城市中间修筑路径使其连通并且花费最小引出.如下图所示引例. 多数求最小生成树算法都应用了简称为MST的性质:假设N=(V,{E})是一个连通网,U是顶点V的一个非空子集.若 ...

  2. 【HDU - 1301】Jungle Roads(并查集+最小生成树)(内附最小生成树两种算法 克鲁斯特尔算法amp;amp;普里姆算法)

    题干: Jungle Roads Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  3. hdu 1233 还是畅通工程(最小生成树的Prim和Kruskal两种算法的c++实现)(prim算法详解)...

    赤裸裸滴最小生成树(MST),刚学的玩意,用两种方法熟练一下.(都是greedy) Kruskal方法:先对边按照代价非递减排序,再不断添加边且不产生环路,当边数=点数-1结束.判断加入(v,w)是否 ...

  4. 理解最小生成树与权值最小边无关

    理解最小生成树与权值最小边无关 @(算法学习) 驳斥:具有n个顶点的有向图G的最小生成树不唯一,则其权值最小的边一定有多条. 有两种最小生成树,但是实际上权值最小的边只有一条. 更简洁的说,最小生成树 ...

  5. 求一个数的二进制中有多少了 1 的三种算法 ——Java篇

    求一个数的二进制中有多少了 1 的三种算法 --Java篇 文章目录 求一个数的二进制中有多少了 1 的三种算法 --Java篇 算法一:通过取模 % 运算就取出每一比特位数值,再判断 思路: 代码: ...

  6. poj2349:Arctic Network(最小生成树)

    总时间限制:  2000ms  内存限制:  65536kB 描述 The Department of National Defence (DND) wishes to connect several ...

  7. 用Prim和Kruskal两种算法,求解最小生成树

    本文通过具体的算法模板题,给出Prim和Kruskal两种求解最小生成树求解过程和代码~ 由浅入深,通俗易懂 题目选自洛谷P3366 题目描述 如题,给出一个无向图,求出最小生成树,如果该图不连通,则 ...

  8. java二叉树求权值_百度笔试题目:二叉树路径权值和【转】

    数据结构课程 百度笔试题目: 给出一个二叉树,和一个整型值,求出二叉树上所有从根到叶子的路径,并且此路径上各个节点的权值之和等于给出的整型值. 解题思路: 根据二叉树的先根遍历思想,通过一个栈保存从根 ...

  9. 求序列中第k大的元素(划分树模板)

    http://acm.hdu.edu.cn/showproblem.php?pid=4251 n个数,求给定区间中间大小的元素的值 Sample Input 5 5 3 2 4 1 3 1 3 2 4 ...

最新文章

  1. 英国工程巨头遭勒索攻击:运营临时中断 至少损失4亿元
  2. 01移动端布局基础之流式布局
  3. MySQL 7种日志类型 详解
  4. 频谱扩展 matlab,简单的直接扩展频谱通信系统仿真分析
  5. PHP实现Restful风格的API(转)
  6. 服务器系统怎么打驱动精灵,win7系统如何使用驱动精灵?教你在win7系统使用驱动精灵的方法...
  7. Redis生成自增流水号,每日清零
  8. 计算机主板清理,终于理解如何清洗电脑主板
  9. 前言(2):什么是微服务?
  10. VMware14 kali linux安装教程
  11. JS如何获取屏幕、浏览器及网页高度宽度?
  12. Python双均线策略回测(2021-10-12)
  13. speedoffice使用方法-Word如何分栏
  14. 咸鱼CAD笔记—精准绘图
  15. win10自动重启另辟蹊径解决方案
  16. 工程导论-----工程,技术与工程师
  17. 神奇了!AR技术可测量实物体积!
  18. Finger Names 你知道五根手指的英文名吗?
  19. Character-level Convolutional Networks for Text Classification之每日一篇
  20. 物联网最常见的5个核心关键技术与2种技术难点

热门文章

  1. android 广播唤醒应用,Android通过广播实现灭屏和唤醒
  2. oracle自动备份定时任务,Oracle数据库定时自动备份批处理代码(Windows)
  3. 福师2018计算机应用基础,中石油华东《计算机应用基础》2018年秋学期在线作业100分答案满分...
  4. 适合文科女孩子学的计算机类专业,文科女生最吃香的专业2021 哪些专业有前景...
  5. spring security:自定义认证成功处理器
  6. stat函数_数据分析工具入门 掌握这些Excel函数就够了
  7. access vba代码大全_VBA 实践指南 -- VBA连接各种数据库
  8. 开源应用架构之asterisk
  9. linux内核设计与实现 怎么读,《Linux内核设计与实现》读书笔记(一)
  10. mysql 碎片率_计算MySQL表碎片的SQL整理