Загрузка данных
#include <iostream>
#include <vector>
using namespace std;
// ============================================================
// ЗАДАЧА 4: количество вершин в компоненте связности (матрица смежности)
// ============================================================
void task4() {
// Объявляем переменные
int n, S; // n — число вершин, S — стартовая вершина
cin >> n >> S; // читаем их с ввода
S--; // переводим S в 0-индексацию (в условии нумерация с 1)
// Создаём матрицу смежности размером n x n (макс 100)
int matrix[100][100];
// Читаем матрицу
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> matrix[i][j];
}
}
// Массив посещённых вершин (0 — не посещена, 1 — посещена)
int visited[100] = {};
// Счётчик вершин в компоненте
int count = 0;
// Рекурсивная функция DFS (лямбда или локальная функция не разрешена в старом C++,
// поэтому объявляем её внутри как вложенную функцию через struct или используем глобальные переменные.
// Для простоты сделаем её отдельной функцией внутри, но в C++ нельзя объявлять функции внутри функций.
// Используем глобальные переменные для этого случая.
// В целях упрощения перепишем без вложенной функции, а просто объявим глобальную функцию,
// но для автономности я оформлю через указатели на матрицу и массивы — но проще сделать отдельную функцию,
// которая принимает матрицу и массивы как параметры.
// Однако для чистоты кода я создам отдельную функцию dfs4, которая использует глобальные переменные,
// но мы можем передавать параметры через ссылки. Но проще сделать всё в одной функции task4,
// используя лямбду (C++11). Так как мы не ограничены, используем лямбду.
// Для совместимости с C++98 можно использовать отдельную функцию, но мы напишем лямбду.
// Используем std::function, но проще объявить функцию внутри через auto и recursive lambda.
// Но мы можем обойтись без рекурсивной лямбды, используя стек или явный вызов.
// Для простоты и наглядности я создам глобальную функцию dfs4, но для целостности задачи
// я предпочту использовать отдельную функцию с передачей параметров по ссылке.
// Так как это объяснительный код, я вынесу DFS в отдельную функцию вне task4,
// но тогда она будет использовать глобальные переменные. Сделаем проще: используем лямбду с std::function.
// Но я хочу избежать сложностей. Поэтому я напишу отдельную функцию dfs4, которая принимает
// матрицу, visited и count по ссылке.
// Я перепишу задачу 4 так, чтобы функция dfs4 была отдельной, но объявлена внутри task4 не получится,
// поэтому я объявлю глобальную функцию, которая принимает матрицу, visited и count по ссылке.
// Для удобства и читаемости я всё-таки использую лямбду (C++11), так как это современный подход.
// Если препод не разрешает, можно заменить на отдельную функцию.
// Объявляем лямбду-функцию dfs, которая захватывает все переменные по ссылке
// и может вызывать себя рекурсивно. Для рекурсивной лямбды нужно использовать std::function,
// либо передавать её саму в качестве аргумента. Для простоты я сделаю обычную функцию вне.
}
// Но чтобы не усложнять, я лучше вынесу DFS в отдельную глобальную функцию.
// Для задачи 4 я создам глобальные переменные: mat4, vis4, n4, cnt4.
// Это самый простой способ без лямбд.
// Глобальные переменные для задачи 4
int mat4[100][100];
int vis4[100];
int n4;
int cnt4;
void dfs4(int v) {
vis4[v] = 1; // помечаем вершину как посещённую
cnt4++; // увеличиваем счётчик
for (int i = 0; i < n4; i++) {
if (mat4[v][i] == 1 && vis4[i] == 0) {
dfs4(i); // рекурсивно обходим соседа
}
}
}
void task4() {
int S;
cin >> n4 >> S;
S--;
for (int i = 0; i < n4; i++) {
for (int j = 0; j < n4; j++) {
cin >> mat4[i][j];
}
}
for (int i = 0; i < n4; i++) vis4[i] = 0; // обнуляем массив посещений
cnt4 = 0;
dfs4(S);
cout << cnt4 << endl;
}
// ============================================================
// ЗАДАЧА 5: проверка на двудольность (две группы)
// ============================================================
// Глобальные переменные для задачи 5
vector<int> graph5[100];
int color5[100];
int n5, m5;
bool dfs5(int v, int c) {
color5[v] = c; // красим текущую вершину в цвет c
for (int u : graph5[v]) { // перебираем соседей
if (color5[u] == -1) { // если сосед не окрашен
if (!dfs5(u, 1 - c)) return false; // запускаем с противоположным цветом
} else if (color5[u] == c) { // если сосед уже окрашен и цвет совпадает
return false; // конфликт, граф не двудольный
}
}
return true; // всё хорошо
}
void task5() {
cin >> n5 >> m5;
for (int i = 0; i < n5; i++) graph5[i].clear(); // очищаем списки смежности
for (int i = 0; i < m5; i++) {
int u, v;
cin >> u >> v;
u--; v--;
graph5[u].push_back(v);
graph5[v].push_back(u); // неориентированный граф, добавляем оба направления
}
for (int i = 0; i < n5; i++) color5[i] = -1; // инициализируем цвета
bool bipartite = true;
for (int i = 0; i < n5; i++) {
if (color5[i] == -1) {
if (!dfs5(i, 0)) {
bipartite = false;
break;
}
}
}
cout << (bipartite ? "YES" : "NO") << endl;
}
// ============================================================
// ЗАДАЧА 6: есть ли цикл в ориентированном графе
// ============================================================
int n6, m6;
vector<int> graph6[100000];
int state6[100000]; // 0 - не посещена, 1 - в стеке, 2 - обработана
bool dfs6(int v) {
state6[v] = 1; // помечаем, что вошли в вершину
for (int u : graph6[v]) {
if (state6[u] == 0) { // если не посещена
if (dfs6(u)) return true;
} else if (state6[u] == 1) { // если в стеке, значит, нашли цикл
return true;
}
}
state6[v] = 2; // выходим, помечаем обработанной
return false;
}
void task6() {
cin >> n6 >> m6;
for (int i = 0; i < n6; i++) graph6[i].clear();
for (int i = 0; i < m6; i++) {
int u, v;
cin >> u >> v;
u--; v--;
graph6[u].push_back(v); // ориентированное ребро
}
for (int i = 0; i < n6; i++) state6[i] = 0;
bool hasCycle = false;
for (int i = 0; i < n6; i++) {
if (state6[i] == 0) {
if (dfs6(i)) {
hasCycle = true;
break;
}
}
}
cout << (hasCycle ? 1 : 0) << endl;
}
// ============================================================
// ГЛАВНАЯ ФУНКЦИЯ
// ============================================================
int main() {
// Раскомментируйте нужную задачу:
// task4(); // компонента связности
// task5(); // двудольность
// task6(); // цикл в ориентированном графе
return 0;
}