Реши задачу на c++ Задача J. План Б Ограничение по...
創建於:2025年12月6日
使用 GPT-5.1 Thinking 回答 Chat01
創建於:2025年12月6日
使用 GPT-5.1 Thinking 回答 Chat01
Реши задачу на c++ Задача J. План Б
Ограничение по времени: 0.25 секунд
Ограничение по памяти: 256 мегабайт
В Кризисной Земле время от времени происходят кризисы, которые серьезно угрожают безопас-
ности страны. В недавнем кризисе в нескольких городах страны произошла серия гражданских
протестов. Протест начался в одном городе и быстро распространился на другие города. Чтобы
предотвратить это в будущем, правительство в качестве Плана Б — после отключения интернета
по всей стране — решило быстро отправить армию, чтобы окружить город, из которого начинается
протест. Город считается окруженным, если в каждом из его соседних городов находятся армейцы.
У правительства есть военные базы в b различных городах, каждая из которых имеет много армей-
цев, которые могут быть отправлены во все города. Правительство знает, что его армия не может
пройти через город, из которого начинается протест, так как они могут быть убиты. Учитывая это,
может случиться так, что некоторые города невозможно окружить армией. Эти города называют-
ся критическими. Предполагается, что если в городе есть военная база, то этот город не является
критическим. Теперь правительство хочет узнать, есть ли критические города в стране или нет.
Помогите правительству найти ответ.
О, мы забыли объяснить структуру Кризисной Земли! Чтобы разрешить этот кризис, следует
упомянуть, что Кризисная Земля состоит из n городов, пронумерованных от 1 до n. Города со-
единены m дорогами, которые могут использоваться в обоих направлениях. Два города являются
соседями,еслимеждунимиестьдорога.Гарантируется,чтодорожнаясетьКризиснойЗемлисвязна.
Формат входных данных
Первая строка входных данных содержит три положительных целых числа n, m и b, обозначаю-
щих количество городов, дорог и военных баз соответственно (1 ⩽ b ⩽ n ⩽ 100 000, 1 ⩽ m ⩽ 200 000).
Каждая из следующих m строк содержит два числа vi и ui, обозначающих дорогу между городами
vi и ui. Последняя строка состоит из b целых чисел, представляющих города, имеющие военную
базу.
Формат выходных данных
Выходные данные состоят из двух строк. Первая строка содержит количество критических го-
родов. Вторая строка содержит критические города в порядке возрастания.
Пример
стандартный ввод стандартный вывод
7 8 3
1
1 2
3
1 3
1 4
2 5
2 6
5 6
3 4
3 7
4 5 6
Решать будем через точки сочленения (articulation points).
Для города :
Город критичен, если
Замечания:
Сделаем один DFS (Таръян):
tin[v] — время входа в DFS,low[v] — минимальное tin вершины, достижимой из поддерева v по одному дереву DFS + одному обратному ребру,u — точка сочленения, если:
v такой, что low[v] >= tin[u].Параллельно считаем:
subtreeBase[v] — количество баз в поддереве v дерева DFS.u храним список childComps[u] — числа баз в тех поддеревьях детей v, которые образуют отдельные компоненты после удаления u:
subtreeBase[v], если low[v] >= tin[u];Пусть totalBases — общее число городов с базами.
Тогда для города u:
u есть база — он по условию не критичен, пропускаем;u — корень DFS:
childComps[u].0 баз ⇒ u критичен.u — некорень:
childComps[u] пустой → u не точка сочленения → не критичен;u:
x в childComps[u] — отдельная «дочерняя» компонента с x базами;parentBases = totalBases - (есть ли база в u) - sum(childComps[u]).x из childComps[u] или parentBases) равна 0, то u — критичен.Сложность:
DFS по графу , памяти тоже , что подходит под ограничения.
cpp#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, m, b; if (!(cin >> n >> m >> b)) return 0; vector<vector<int>> g(n + 1); for (int i = 0; i < m; ++i) { int u, v; cin >> u >> v; g[u].push_back(v); g[v].push_back(u); } vector<bool> isBase(n + 1, false); int totalBases = 0; for (int i = 0; i < b; ++i) { int x; cin >> x; if (!isBase[x]) { // на всякий случай, вдруг дубликаты isBase[x] = true; ++totalBases; } } vector<int> tin(n + 1, 0), low(n + 1, 0), parent(n + 1, -1); vector<int> subtreeBase(n + 1, 0), rootChildren(n + 1, 0); vector<bool> used(n + 1, false); vector<vector<int>> childComps(n + 1); // количества баз в отделившихся поддеревьях int timer = 0; function<void(int,int)> dfs = [&](int u, int p) { used[u] = true; parent[u] = p; tin[u] = low[u] = ++timer; subtreeBase[u] = isBase[u] ? 1 : 0; int children = 0; for (int v : g[u]) { if (v == p) continue; if (used[v]) { // обратное ребро low[u] = min(low[u], tin[v]); } else { dfs(v, u); low[u] = min(low[u], low[v]); subtreeBase[u] += subtreeBase[v]; ++children; if (p == -1) { // корень: каждое поддерево ребёнка - отдельная компонента после удаления корня childComps[u].push_back(subtreeBase[v]); } else if (low[v] >= tin[u]) { // отделившаяся компонента childComps[u].push_back(subtreeBase[v]); } } } if (p == -1) { rootChildren[u] = children; } }; // Граф по условию связный, но на всякий случай обойдём все компоненты for (int i = 1; i <= n; ++i) { if (!used[i]) dfs(i, -1); } vector<int> critical; for (int u = 1; u <= n; ++u) { if (isBase[u]) continue; // по условию такие города не критичны if (parent[u] == -1) { // корень DFS if (rootChildren[u] <= 1) continue; // не точка сочленения bool bad = false; // есть ли компонента без базы for (int x : childComps[u]) { if (x == 0) { bad = true; break; } } if (bad) critical.push_back(u); } else { // некорень if (childComps[u].empty()) continue; // не точка сочленения long long sumChild = 0; bool bad = false; for (int x : childComps[u]) { sumChild += x; if (x == 0) bad = true; // дочерняя компонента без базы } int parentBases = totalBases - (isBase[u] ? 1 : 0) - (int)sumChild; if (parentBases == 0) bad = true; // родительская компонента без базы if (bad) critical.push_back(u); } } sort(critical.begin(), critical.end()); cout << critical.size() << "\n"; if (!critical.empty()) { for (size_t i = 0; i < critical.size(); ++i) { if (i) cout << ' '; cout << critical[i]; } cout << "\n"; } else { cout << "\n"; // вторая строка пустая } return 0; }
Если хочешь, могу отдельно нарисовать маленький пример и пошагово показать, как для него работают tin/low и подсчёт баз по компонентам.