GDUT_寒假训练题解报告_图论专题_个人题解报告——题目:E -Arctic Network

GDUT_寒假训练题解报告_图论专题_个人题解报告——题目:E -Arctic Network

题目:

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

不用翻译了,中文就是:

国防部希望通过无线网络连接几个北方前哨基地。 在建立网络时将使用两种不同的通信技术:每个前哨基站都将拥有无线电收发器,另外还有一些前哨卫星通道。

任何带卫星频道的两个前哨都可以通过卫星进行通信,无论其位置如何。 否则,只有两个前哨基站之间的距离不超过D,才能通过无线电通信,这取决于收发器的功 率。 更高的功率产生更高的D,但成本更高。 由于采购和维护的考虑,前哨收发器必须相同; 也就是说,D的价值对于每对前哨都是一样的。

您的工作是确定收发器所需的最小D。 在每对前哨之间必须至少有一条通信路径(直接或间接)。

输入:

第一行输入包含N个测试用例数。 每个测试用例的第一行包含1 <= S <= 100,卫星通道数,S <P <= 500,前哨数。 遵循P行,给出每个前哨的(x,y)坐标,单位为km(坐标为0和10,000之间的整数)。

输出:

对于每种情况,输出应由一条线组成,给出连接网络所需的最小D。 输出应指定为2个小数点。

这是一个这样的题干,给定P个点的坐标,让你求去除S个点之后的图所形成的树的最长边最小,也就是说这个就是一个最小生成树的板子题目,只不过是浮点型的数据而已,
然后看最后的处理:

point=0;
		tot=0;
		for(int time1=0;time1<m;time1++)
		{
			if(point==p-s)break;
			if(father(es[time1].from)!=father(es[time1].to))
			{
				merge(es[time1].from,es[time1].to);
				point++;
				tot=es[time1].value;//tot记录生成树里面最长的一个边作为答案半径
			}
		}

原本的板子里面是point==P-1,但是你去除了s个点,而且要拿到下一条边。也就是两个连通块要连接的地方,这个可能大家听不懂,换句话说,这个最长边,也就是最长的半径,他一定连接无卫星通讯的哨站和有卫星通讯的哨站:
有卫星的哨站是一个连通块,你获得的无卫星的连通块的最小生成树要相连接,那么只能从已经sort好的es[]数组里面获取下一个长度的边,所以point结束值不是p-s-1而是p-s。
完整代码如下:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <climits>
#include <queue>
#include <stack>
#include <map>
//鬼畜头文件
using namespace std;
#define INF 0x3f3f3f3f
#define ULL unsigned long long
#define LL long long
//鬼畜define
//
int coordinate_x[505];
int coordinate_y[505];
typedef struct edge
{
	int from;
	int to;
	double value;
};
edge es[125010];
int fa[510];
void disjoint_set(int n)
{
	for(int time=0;time<n;time++)
	{
		fa[time]=time;
	}
}
int father(int x)
{
	if(x==fa[x])return x;
	else return father(fa[x]);
}
bool cmp(const edge &a,const edge &b)
{
	return a.value<b.value;
}
void merge(int a,int b)
{
	int x=father(a);
	int y=father(b);
	if(x!=y)
	{
		fa[y]=x;
	}
}
int t;
int m;
int s,p;
int point;
double tot;

int main()
{
	scanf("%d",&t);
	for(int time=0;time<t;time++)
	{
		scanf("%d %d",&s,&p);
		m=p*(p-1)/2;
		for(int time1=0;time1<p;time1++)
		{
			scanf("%d %d",&coordinate_x[time1],&coordinate_y[time1]);
		}
		int now=0;
		for(int time1=0;time1<p;time1++)
		{
			for(int time2=time1+1;time2<p;time2++)
			{
				es[now].from=time1;
				es[now].to=time2;
				es[now].value=sqrt( (coordinate_x[time1]-coordinate_x[time2])*(coordinate_x[time1]-coordinate_x[time2]) + (coordinate_y[time1]-coordinate_y[time2])*(coordinate_y[time1]-coordinate_y[time2])  );
				now++;
			}
		}
		//input finished
		disjoint_set(p);
		sort(es,es+m,cmp);
		point=0;
		tot=0;
		for(int time1=0;time1<m;time1++)
		{
			if(point==p-s)break;
			if(father(es[time1].from)!=father(es[time1].to))
			{
				merge(es[time1].from,es[time1].to);
				point++;
				tot=es[time1].value;//tot记录生成树里面最长的一个边作为答案半径
			}
		}
		printf("%.2f\n",tot);
	}
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值