10203. Arctic network
The Ministry of
National Defense (MND) plans to connect several northern outposts into a single
wireless network. Two different communication technologies must be used to
build the network: each outpost will be equipped with a radio transceiver, and
some of them will additionally have a satellite channel.
Any two outposts
equipped with a satellite channel can communicate with each other via
satellite, regardless of the distance between them. Otherwise, two outposts can
communicate by radio only if the distance between them does not exceed d, which depends on the power of the
transceivers. The higher the power, the larger the value of d, but the cost of the equipment also
increases. For economic and maintenance reasons, all transceivers must be
identical, meaning that the value of d must
be the same for all pairs of outposts.
You must
determine the minimum value of required so that communication is
possible between any two outposts – either directly or indirectly (through
other outposts).
Input. The first line
contains the number of test cases n.
The first line of each test case contains the number of satellite
channels s (1 ≤ s ≤ 100) and
the number of outposts p (s < p ≤ 500).
Each of the next p lines
contains the coordinates (x, y) of an outpost in kilometers
(integers from 0 to 10000).
Output. For each test
case, print the minimum value of d required
to connect all outposts into a single network. Print the result with exactly
two digits after the decimal point.
Sample
input |
Sample
output |
1 2 4 1 0 3 0 6 0 7 2 |
2.24 |
graphs – Prim algorithm
Start Prim’s algorithm.
Construct an array dist,
where dist[i]
stores the length of the shortest edge from MST that runs to the vertex i. That is, MST consists of these edges.
Moreover, dist[0] = 0, since we start the algorithm
from the vertex 0.
At the end of Prim’s algorithm,
sort the dist
array. The most distant outposts should be connected by satellite channels.
They should be placed in those s outposts
that connect the longest edges from dist (s – 1 edges
connect s outposts). Therefore, the
desired value of d will be the length
of the edge that is the s-th from the end of dist.
Example
Consider the graph given
in a sample.
Put two satellite
channels at points (3; 0) and (6; 0). Thus, the outposts in these coordinates
are connected via satellite. Find
the largest one among the remaining edges of MST. This will be the edge
connecting the points (6; 0) and (7; 2), its length is 2.24.
Declare
global arrays. Store the coordinates of the outposts in (x[i], y[i]).
used[i] = 1, if vertex i is included in MST.
#define MAX 501
#define INF
0x3F3F3F3F
int x[MAX], y[MAX];
int used[MAX], dist[MAX];
The function dist2 computes the squared
distance between outposts i and j.
int dist2(int i, int j)
{
return (x[j] -
x[i])*(x[j] - x[i]) +
(y[j] - y[i])*(y[j] -
y[i]);
}
Function Prim implements the Prim’s
algorithm.
void Prim(void)
{
Initialize the
arrays.
memset(dist, 0x3F, sizeof(dist));
memset(used, 0, sizeof(used));
Start building
the MST from the vertex 0. Initialize dist[0]
= 0, used[0] = 1.
int i,
j, cur = 0;
dist[cur] = 0;
used[cur]
= 1;
Make n – 1 iterations. At
each iteration, add one vertex
to MST (so n – 1 vertices should
be added to MST).
for (i =
1; i < n; i++)
{
The current vertex is cur.
Iterate over
the edges (cur, j) and recalculate the value of dist[j]. Thus dist[j] stores the current
shortest distance from vertex j to
the current MST.
for (j =
0; j < n; j++)
if
(!used[j] && (dist2(cur, j) < dist[j]))
dist[j] = dist2(cur,
j);
We are looking for the shortest edge
that will be included in
MST. To do this, look for the smallest dist[j] such that the vertex j does
not yet belong
to MST (used[j] = 0). The number of the
vertex with the smallest dist[j] is stored into
cur (it becomes the
current one).
int min
= INF;
for (j =
0; j < n; j++)
if
(!used[j] && (dist[j] < min))
{
min = dist[j];
cur = j;
}
Vertex cur is included to MST.
used[cur]
= 1;
}
}
The main part of the program.
Process tests tests.
scanf("%d", &tests);
while (tests--)
{
Read
the input data.
scanf("%d
%d", &s, &n);
for (i =
0; i < n; i++)
scanf("%d
%d", &x[i], &y[i]);
Run
the Prim’s algorithm.
Prim();
Sort
the array dist.
sort(dist, dist + n);
Print
the answer.
printf("%.2lf\n",
sqrt(dist[n - s]));
}
Java realization
import java.util.*;
public class Main
{
static int n;
static int x[], y[];
static int used[], dist[];
static int
dist2(int i, int j)
{
return (x[j] - x[i])*(x[j] - x[i]) +
(y[j] - y[i])*(y[j] - y[i]);
}
static void
Prim()
{
dist
= new int[n];
Arrays.fill(dist, Integer.MAX_VALUE);
used = new int[n];
int i, j, cur = 0;
dist[cur] =
0;
used[cur] =
1;
for (i = 1;
i < n; i++)
{
for (j = 0;
j < n; j++)
if (used[j] ==
0 && dist2(cur, j)
< dist[j])
dist[j] = dist2(cur, j);
int min = Integer.MAX_VALUE;
for (j = 0;
j < n; j++)
if (used[j] ==
0 && dist[j]
< min)
{
min = dist[j];
cur = j;
}
used[cur] =
1;
}
}
public static void
main(String[] args)
{
Scanner con = new
Scanner(System.in);
int tests = con.nextInt();
while (tests--
> 0)
{
int s = con.nextInt();
n = con.nextInt();
x = new int[n];
y = new int[n];
for (int i = 0;
i < n; i++)
{
x[i] = con.nextInt();
y[i] = con.nextInt();
}
Prim();
Arrays.sort(dist);
System.out.println(Math.sqrt(dist[n - s]));
}
con.close();
}
}