Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 12253 | Accepted: 4001 |
Description
Input
Output
Sample Input
1 2 4 0 100 0 300 0 600 150 750
Sample Output
212.13
Source
直接读错题。。以为是建S个生成树。。。。
题目大意: 有一些炮台,如果这个炮台有卫星接收器,那么任意两个有卫星接收器的炮台可以通信,不受距离限制;否者,两个炮台之间只能通过对讲机通信,这是受距离限制的。要买一种对讲机,用在需要的炮台上,要求所有炮台两两之间可以直接或者间接通信,问要买通信距离至少为多少的对讲机可以满足要求。输入:S卫星接收器的数量,P炮台的数量,然后是P行,每行代表一个炮台的坐标。输出要求的对讲机的通信距离D。
因为是有S个卫星 贪心思想肯定是距离最远的S个点有这几个卫星 所以可以直接将这个几个卫星利用prim算法 然后用数组记录下 最小生成树的距离和原始距离的二者最小值。。 最后对该数组从大到小排序 然后输出第S个 即下标S-1的数组。
#include <stdio.h> #include <string.h> #include <math.h> #include <algorithm> #define INF 0x3f3f3f3f using namespace std; bool used[510]; double cost[510][510]; double d[510]; int V; int k; double ans[510]; struct Point{ double x,y; }point[510]; bool cmp(double a,double b) { return a>b; } void prim() { for(int i=0;i<V;i++) { used[i]=false; d[i]=INF; } d[0]=0; double res=0; while(1) { int v=-1; for(int i=0;i<V;i++) { if(!used[i]&&(v==-1||d[v]>d[i]))v=i; } if(v==-1)break; used[v]=true; res+=d[v]; ans[k++]=d[v]; for(int i=0;i<V;i++) { d[i]=min(d[i],cost[v][i]); } } } int main() { int t; int N; scanf("%d",&t); while(t--) { k=0; memset(ans,0,sizeof(ans)); scanf("%d%d",&N,&V); double a,b; for(int i=0;i<V;i++) { scanf("%lf%lf",&point[i].x,&point[i].y); for(int j=i;j<V;j++) { cost[i][j]=cost[j][i]=INF; } } for(int q=0;q<V;q++) { for(int w=q+1;w<V;w++) { double tmp1=(point[q].x-point[w].x)*(point[q].x-point[w].x); double tmp2=(point[q].y-point[w].y)*(point[q].y-point[w].y); double tmp=sqrt(tmp1+tmp2); cost[q][w]=cost[w][q]=tmp; } } prim(); sort(ans,ans+k,cmp); //for(int i=0;i<k;i++) //printf("%lf**",ans[i]); printf("%.2lf\n",ans[N-1]); } return 0; }