[hoj 2507]The Bug Sensor Problem[第k长路]

来源:互联网 发布:python爬虫可以赚钱吗 编辑:程序博客网 时间:2024/05/21 07:39

题意:

给出一些点的坐标, 求这些点之间的第k长边.


本来的描述是, 一些点, 有效距离之内可以传送数据, 有效距离也表示耗电量. 可以放k个收发器, 收发器的有效距离无穷大. 所有点的耗电量设为相同, 问此时单点耗电量最小是多少.

思路:

先求最小生成树, 放k个传感器的话, 可以省去k-1条边(就是直接发走而不需要走这条边), 那么求出第k长边即可.


特殊的,未加优化的prim:

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include <stack>#include <queue>#include <algorithm>#include <iostream>using namespace std;#define Maxn 100005#define INF 0x3f3f3f3fstruct Point{double x,y;}point[Maxn];double dist[Maxn];int vis[Maxn];int s,p;int m;double ans[Maxn];double getDis(Point a,Point b){return sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y));}/**prim算法的基本思路:MST点集A和未加入MST点集~A, 每次从~A中找到到A中的点距离最近的点, 加入A. 重复这个过程, 直到~A为空.要点是找到那个"距离最近的点"*/void prim(){dist[0] = 0;//每次都从0这个点出发for(int i=1;i<p;i++){dist[i] = INF;//初始化为正无穷, 还没开始扩展}memset(vis,0,sizeof(vis));//都未拜访m = 0;//ans的游标for(int i=0;i<p;i++)//遍历每一个点,i{double mi = INF;int mik;//存最近距离和最近点for(int j=0;j<p;j++)//遍历每一个点,j{if(dist[j]<mi && !vis[j]) mi = dist[j],mik = j;//找到最近距离和最近点,通过初始化启动算法}//dist[j]表示j点到A集合的最小距离.ans[m++] = mi;vis[mik] = 1;for(int j=0;j<p;j++)//本题比较特殊,给的是点,可以直接计算邻接的边,松弛.{//mik是新加点, 每次只需更新这一点.if(dist[j]> getDis(point[mik],point[j])) dist[j] = getDis(point[mik],point[j]);}}}int main(){int w;double a,b;scanf("%d",&w);while(w--){p = 0;scanf("%d",&s);while(scanf("%lf",&a)==1 && a!=-1){scanf("%lf",&b);point[p].x = a,point[p].y = b;p++;}prim();        sort(ans+1,ans+m);        //第一条边是0号点与MST所在连通分量的距离,为0,不参加边长的比较        //m已经++过了,故可以直接用+m作为end指针.        printf("%.0f\n",ceil(ans[p-s]));}return 0;}