Arctic Network
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 27131 | Accepted: 8246 |
Description
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座村庄,每座村庄的坐标用一对整数(x, y)表示,现在要在村庄之间建立通讯网络。
•通讯工具有两种,分别是需要铺设的普通线路和无线通讯的卫星设备。
•只能给k个村庄配备卫星设备,拥有卫星设备的村庄互相间直接通讯。
•铺设了线路的村庄之间也可以通讯。但是由于技术原因,两个村庄之间线路长度最多不能超过 d, 否则就会由于信号衰减导致通讯不可靠。要想增大 d 值,则会导致要投入更多的设备(成本)
思路:
有n个村庄,使n个村庄相联系,需要n-1条路,有k个卫星,k个卫星可以代替k-1条路,其他路需要铺设线路,但要是线路最小,可以找出最小生成树,村村连通的最短距离可以知道,这n-1条路中用卫星代替k-1条最大的路,则剩下的路中长度最大的值就是d的最小值。
用了kruskal算法:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cmath>
#define p 501
using namespace std;
struct road{
int u;
int v;
double l;
road(int uu,int vv,double ll):u(uu),v(vv),l(ll){}
bool operator<(const road &r)const{
return l<r.l;
}
};
vector <road> roads;
vector <int> par;
double a[p];//存放最小生成树的各个边
int getroot(int a){
if(par[a]!=a){
par[a]=getroot(par[a]);
return par[a];
}
return a;
}
void Merge(int a,int b){
int pa=getroot(a);
int pb=getroot(b);
if(pa==pb){
return;
}
par[pb]=pa;
}
int main(){
int n;
int x[p],y[p];
scanf("%d",&n);
for(int i=0;i<n;i++)
{
par.clear();//不要忘了每次测试前清空数据!!!1
roads.clear();
memset(a,0,sizeof(a));
int m,k;//m个城市,k个卫星
scanf("%d%d",&k,&m);
for(int i=0;i<m;i++)
{
scanf("%d%d",&x[i],&y[i]);
par.push_back(i);
}
for(int i=0;i<m;i++)
{
for(int j=0;j<m;j++)
{
double l=sqrt((y[j]-y[i])*(y[j]-y[i])*1.0+(x[j]-x[i])*(x[j]-x[i]));
//printf("l;%.2f\n",l);
roads.push_back(road(i,j,l));
}
//printf("-----------\n");
}
sort(roads.begin(),roads.end());
int done=0;
int j=0;
for(int i=0;i<roads.size();i++)
{
if(getroot(roads[i].u)!=getroot(roads[i].v))
{
done++;
//total+=roads[i].l;
a[j++]=roads[i].l;
Merge(roads[i].u,roads[i].v);
}
}
sort(a,a+j);
/*for(int i=0;i<j;i++){
printf("%.2f",a[i]);
}*/
if(done==n-1)
{
break;
}
printf("%.2f\n",a[j-k]);
}
}