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 750Sample Output
212.13题意:有S颗卫星和P个哨所,有卫星的两个哨所之间可以任意通信;否则,一个哨所只能和距离它小于等于D的哨所通信。给出卫星的数量和P个哨所的坐标,求D的最小值。
分析:这是一个最小生成树问题。P个哨所最多用P-1条边即可连起来,而S颗卫星可以代替S-1条边,基于贪心思想,代替的边越长,求得的D就越小。所以可以用一个数组保存加入最小生成树的边的长度,共有P-1条边,把前S-1条较长的边代替掉,剩下的边中最长的即为所求,所以Kru加边至第(P-1)-(S-1)=P-S条边即为所求。
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<algorithm> using namespace std; int f[1005],x[1005],y[1005]; struct Node{ int u,v; double w; }edge[150005]; bool cmp(Node a,Node b) { return a.w<b.w; } int find(int x) { return f[x]==x?x:f[x]=find(f[x]); } double kru(int s,int n,int m) { int i; for(i=1;i<=n;i++){ f[i]=i; } sort(edge+1,edge+m+1,cmp); int cnt=0; double ans=0; for(i=1;i<=m;i++){ int u=edge[i].u; int v=edge[i].v; double w=edge[i].w; int fu=find(u),fv=find(v); if(fu!=fv){ ans=w; f[fv]=fu; cnt++; } if(cnt==n-s) break; } if(cnt<n-s) return -1; else return ans; } int main() { int t,s,n,m,i,j; scanf("%d",&t); while(t--){ scanf("%d%d",&s,&n); for(i=1;i<=n;i++){ scanf("%d%d",&x[i],&y[i]); } memset(edge,0,sizeof(edge)); int m=0; for(i=1;i<=n;i++){ for(j=i+1;j<=n;j++){ edge[++m].w=sqrt((x[j]-x[i])*(x[j]-x[i])+(y[j]-y[i])*(y[j]-y[i])); edge[m].u=i; edge[m].v=j; } } printf("%.2f\n",kru(s,n,m)); } return 0; }
转载于:https://www.cnblogs.com/yzm10/p/7279756.html
