Олимпиадное программирование

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Олимпиадное программирование » Общий » Города (Красноярск '07)


Города (Красноярск '07)

Сообщений 1 страница 4 из 4

1

Международная олимпиада АСМ по программированию
(четвертьфинал) 2007

Problem B

Cities

Input from file CITIES.IN in the current folder.
Output to the standard output stream (to the display)
Forward the source code to be solved in CITIES.CPP or CITIES.DPR or CITIES.JAVA
Time limit 30 sec
Memory limit 64 Mb

Due to rapid space exploration there appeared a need of reporting chain development for the cities situated on the Mars.
A signal that can be transmitted at distance R is used for reporting. All the cities situated at the distance not farther then R receive the signal and retransmit it along the chain. The system must work in such a way that all the cities, being reported from any other city, receive the signal.
To be found: a minimum range of transmitters when the reporting chain works.

Input data:
The first number is the amount of tests. In the first line of each test there is number n (1 < n < 1000) – the amount of cities. Further n lines go that contain coordinates of the cities xi and yi (-10000 < xi and yi < 10000, x and y are real). Suppose that all of the cities lie in the same plane.

Example of input data:
2
4
0 0
2 0
0 2
2 3
3
2 0
0 2
4 2

Output data:
For each test in a separate line give a minimum range R (accurate within 2 number signs) of the reporting chain.

Example of output data:
2.24
2.83

0

2

import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.Locale;
import java.util.Scanner;

public class Task_B {

public static void main(String[] args) throws IOException {
    Scanner input = new Scanner(new FileReader("CITIES.IN"));
    input.useLocale(Locale.ENGLISH);
    double cit[][] = new double[1000][2], path[][] = new double[1000][1000];
    boolean mark[] = new boolean[1000];
    int k = input.nextInt();
    for (int i=0; i<k; i++) {
    int n = input.nextInt();
    double max = 0;
    Arrays.fill(mark, false);
    for (int j=0; j<n; j++) {
        cit[j][0] = input.nextDouble();
        cit[j][1] = input.nextDouble();       
    }
    for (int i1=0; i1<n; i1++) {
        for (int j1=0; j1<n; j1++) {
        path[i1][j1] = Math.sqrt(Math.pow((cit[i1][0]-cit[j1][0]), 2)+Math.pow((cit[i1][1]-cit[j1][1]), 2));
        if (i1 == j1) {
            path[i1][j1] = Double.MAX_VALUE;
        }
        }
    }
    mark[0] = true;
    int marked = 1;
    while (marked < n) {
        double min = Double.MAX_VALUE;
        int toadd = -1;
        for (int i1=0; i1<n; i1++) {
        if (mark[i1]) {
            for (int j1=0; j1<n; j1++) {
            if ((!mark[j1])&&(path[i1][j1] < min)) {
                min = path[i1][j1];
                toadd = j1;
            }
            }
        }
        }
        if (toadd > -1) {
        mark[toadd] = true;
        marked++;
        if (min > max) max = min;
        }
    }
    System.out.println(Math.round(max*100)/100.0);
    }
}

}

0

3

Идея решения:

Радиус посылаемого сигнала - это, проще говоря, длина ребра, связывающего вершины. Если мы найдем минимальный каркас (т.е. множество ребер, которое нужно, чтобы соединить все вершины так, чтобы из каждой можно было добраться в каждую), то максимальное ребро этого минимального каркаса и будет являться ответом.

Используем алгоритм нахождения каркаса минимального веса (http://istu.mybb.forum/viewtopic.php?pid=14). Создадим множество помеченных вершин, к нему будем добавлять вершины, до которых уже известны кратчайшие пути. Изначально в множестве содержится одна любая вершина, затем запускаем цикл и на каждой итерации добавляем к этому множеству ту вершину, расстояние до которой минимально. Т.е. на каждой итерации мы выясняем расстояния до всех еще не добавленных вершин, выбираем из них минимальное и добавляем эту вершину. Цикл завершается, когда ко множеству добавлены все вершины. В качестве ответа выводим самое длинное ребро каркаса.

Структуры данных:

double cit[][] = new double[1000][2] - координаты всех вершин
path[][] = new double[1000][1000] - матрица смежности (все элементы path[i][i] равны бесконечности, ну, или Double.MAX_VALUE применительно для double. Сделано, чтобы программа не выбирала расстояние от вершины до самой себя в качестве минимального)
boolean mark[] = new boolean[1000] - массив пометок (если mark[i] - true, то вершина добавлена ко множеству)
min - очередное выбранное минимальное расстояние
max - максимальное из всех min, в конце будет выводиться как ответ

Методы:

Нет обособленных, но можно было вынести в метод процесс нахождения расстояния между всеми вершинами и занесения этих расстояний в матрицу смежности

0

4

Я думаю, это правильное решение.

0


Вы здесь » Олимпиадное программирование » Общий » Города (Красноярск '07)