С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
0 / 0 / 0
Регистрация: 03.07.2021
Сообщений: 3
1

Минимизировать количество дорог, которые придётся проехать от заселённого микрорайона до участка

03.07.2021, 14:49. Показов 1009. Ответов 1
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
В городе Bytestree n микрорайонов, соединённых n-1 дорогами с двусторонним движением так, что между любыми двумя микрорайонами можно проехать по сети дорог ровно одним способом. Так как город основан недавно, то заселены только некоторые микрорайоны.

Избирательная комиссия города перед парламентскими выборами решила открыть в одном из микрорайонов (не обязательно в уже заселённом) избирательный участок таким образом, чтобы минимизировать наибольшее количество дорог, которые придётся проехать от заселённого микрорайона до участка.

Требуется найти это расстояние.

Формат ввода
Первая строка входа содержит одно целое число n (2 ≤ n ≤ 106) —количество микрорайонов. Во второй строке заданы n целых чисел — 1, если микрорайон заселён, и 0 в противном случае. Каждая из последующих n-1 строк содержит два целых положительных числа, не превосходящих n — номера микрорайонов, соединённых очередной дорогой.

Формат вывода
Выведите одно целое число — ответ к задаче.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
03.07.2021, 14:49
Ответы с готовыми решениями:

Определить, можно ли в заданной системе односторонних дорог проехать из города А в город В
Определить, можно ли в заданной системе односторонних дорог проехать из города А в город В таким...

Минимизировать стоимость строительства дорог
Нас толкоM не учили такоMу програMMированию, но препод дал такую задачку для решения: Три страны...

Файлы. Определение наименьшего числа конфет, которые придётся съесть Карлсону
Программирование в файлы.

Количество дорог
Напишите программу, которая считает количество дорог в городе Новые Васюки. Схема дорог задана как...

1
458 / 294 / 191
Регистрация: 23.06.2018
Сообщений: 678
04.07.2021, 13:54 2
Простой гугл выдаёт на этом же форуме как минимум идею:
E. Polling Station
Код с рекурсией.
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <iostream>
#include <vector>
 
// Узел дерева/микрорайон
struct node
{
    bool type; // тип микрорайона
    std::vector<node*> near; // микрорайоны соединённые дорогой с текущим
};
 
// Высота поддерева. -1 если в нём нет населённых микрорайонов
int height(const node* root, const node* parent)
{
    int max = root->type - 1;
    for (int i = 0; i < root->near.size(); i++)
    {
        // Пропуск родителя
        if (root->near[i] == parent)
            continue;
        // Поиск максимальной высоты поддерева
        int tmp = height(root->near[i], root);
        if (tmp > max)
            max = tmp + 1;
    }
    return max;
}
 
// Диаметр дерева без ненаселённых микрорайонов
int diameter(const node* root)
{
    int max1 = 0, max2 = 0;
    for (int i = 0; i < root->near.size(); i++)
    {
        int tmp = height(root->near[i], root);
        tmp += tmp != -1; // Высота увеличивается на 1 только если в поддереве есть населённые микрорайоны
        if (tmp > max1)
        {
            max2 = max1;
            max1 = tmp;
        }
        else if (tmp > max2)
        {
            max2 = tmp;
        }
    }
    return max1 + max2;
}
 
void solution(std::istream& in, std::ostream& out)
{
    int tmp;
    // Кол-во узлов
    in >> tmp;
    std::vector<node> nodes(tmp);
    // Считывание типа узлов и поиск потенциального корня
    for (int i = 0; i < nodes.size(); i++)
    {
        in >> nodes[i].type;
        if (nodes[i].type) // Корень - любой населённый микрорайн
            tmp = i;
    }
    // Считывание связей
    for (int i = 1; i < nodes.size(); i++)
    {
        int a, b;
        in >> a >> b;
        a--, b--;
        nodes[a].near.push_back(&nodes[b]);
        nodes[b].near.push_back(&nodes[a]);
    }
    // Ответ
    tmp = diameter(&nodes[tmp]);
    out << tmp / 2 + tmp % 2;
}
 
int main()
{
    // Вынесено в отдельную функцию чтобы можно было заменить на работу с файлами
    solution(std::cin, std::cout);
}


Добавлено через 2 часа 36 минут
Я осознал, что скорее всего вы один из тех людей, кто не проверяет скопированный текст, превращая https://www.cyberforum.ru/cgi-bin/latex.cgi?{10}^{6} в 106. А эта небольшая разница приводит к переполнению стека.
И в итоге кода стало больше...
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include <iostream>
#include <vector>
#include <stack>
 
// Узел дерева/микрорайон
struct tree_node
{
    bool type; // тип микрорайона
    std::vector<tree_node*> near; // микрорайоны соединённые дорогой с текущим
};
 
// Вспомогательная структура для поиска высоты дерева
class trace
{
public:
    const tree_node* node; // узел
    const tree_node* parent; // родитель
    int processed; // обработанных подузлов
    int height; // высота
 
    // Конструктор для упрощения stack.emplace
    trace(const tree_node* node, const tree_node* parent)
    {
        this->node = node;
        this->parent = parent;
        this->processed = 0;
        this->height = node->type - 1;
    }
 
    // Следующий подузел
    const tree_node* next()
    {
        // Пропуск родителя
        if (processed < node->near.size() && node->near[processed] == parent)
            processed++;
        // Подузел или nullptr
        if (processed < node->near.size())
            return node->near[processed++];
        else
            return nullptr;
    }
};
 
// Высота поддерева. -1 если в нём нет населённых микрорайонов
int height(const tree_node* root, const tree_node* parent)
{
    std::stack<trace> backtrace;
    backtrace.emplace(root, parent);
    int max = -1;
    // Пока не проверено всё поддерево
    while (backtrace.size())
    {
        trace& cur = backtrace.top();
        // Обновление максимальной высоты
        if (max > cur.height)
        {
            cur.height = max;
            max = -1;
        }
        // Добавление подузла или извлечение высоты узла
        const tree_node* next = cur.next();
        if (next)
        {
            backtrace.emplace(next, cur.node);
        }
        else
        {
            max = cur.height + (cur.height != -1);
            backtrace.pop();
        }
    }
    return max;
}
 
// Диаметр дерева без ненаселённых микрорайонов
int diameter(const tree_node* root)
{
    int max1 = 0, max2 = 0;
    for (int i = 0; i < root->near.size(); i++)
    {
        int tmp = height(root->near[i], root);
        if (tmp > max1)
        {
            max2 = max1;
            max1 = tmp;
        }
        else if (tmp > max2)
        {
            max2 = tmp;
        }
    }
    return max1 + max2;
}
 
void solution(std::istream& in, std::ostream& out)
{
    int tmp;
    // Кол-во узлов
    in >> tmp;
    std::vector<tree_node> nodes(tmp);
    // Считывание типа узлов и поиск потенциального корня
    for (int i = 0; i < nodes.size(); i++)
    {
        in >> nodes[i].type;
        if (nodes[i].type)
            tmp = i;
    }
    // Считывание связей
    for (int i = 1; i < nodes.size(); i++)
    {
        int a, b;
        in >> a >> b;
        a--, b--;
        nodes[a].near.push_back(&nodes[b]);
        nodes[b].near.push_back(&nodes[a]);
    }
    // Ответ
    tmp = diameter(&nodes[tmp]);
    out << tmp / 2 + tmp % 2;
}
 
int main()
{
    // Вынесено в отдельную функцию чтобы можно было заменить на работу с файлами
    solution(std::cin, std::cout);
}
1
04.07.2021, 13:54
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.07.2021, 13:54
Помогаю со студенческими работами здесь

Сосчитать количество дорог
В галактике «Milky Way» на планете «Snowflake» есть N городов, некоторые из которых соединены...

Сосчитать количество дорог
Помогите пожалуйста решить задачу В галактике &quot;Milky Way&quot; на планете &quot;Neptune&quot; есть N городов,...

Какое максимальное количество паролей придется перебрать?
В некоторой Волшебной стране есть древний храм, двери которого испокон веков закрыты на магический...

Определить, какое наименьшее количество пассажиров придется пересадить.
В час пик на остановку одновременно подъехали три маршрутных такси, следующие по одному маршруту, в...

Количество построенных между городами дорог
Древняя рукопись В некоторой древней стране жили-были братья. Сколько их было, нам точно не...

Сосчитать количество дорог на планете «Snowflake»
В галактике «Milky Way» на планете «Snowflake» есть N городов, некоторые из которых соединены...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
2
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru