diff --git a/readme.md b/readme.md index f57085f09..bc55aad54 100644 --- a/readme.md +++ b/readme.md @@ -18,7 +18,7 @@ | № | ФИО | Directory name | #0 | #1 | #2 | #3 | #4 | #5 | #6 | #7 | Рейтинг | |----|------------------------------------------------------|-------------------------|----|-----|----|----|----|----|----|----|---------| | 1 | Бусень Артём |[ii02301](trunk/ii02301) | ✅ | ✅ | ❌ | ❌ | ✅ | | | | 6| -| 2 | [Волкогон Никита](https://github.com/VolkogonNikita) |[ii02302](trunk/ii02302) | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | | | 8| +| 2 | [Волкогон Никита](https://github.com/VolkogonNikita) |[ii02302](trunk/II02302) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | | 9| | 3 | [Вышинский Артём](https://github.com/arciomwww) |[ii02303](trunk/ii02303) | ✅ | ✅ | ❌ | ❌ | | | | | 6| | 4 | [Гавришук Владислав](https://github.com/VLadGavrishuk)|[ii02304](trunk/ii02304)| ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | | | 7| | 5 | Глухарев Даниил |[ii02305](trunk/ii02305) | ✅ | ✅ | ✅ | ❌ | | | | | 7| diff --git a/trunk/II02302/task_03/doc/1.png b/trunk/II02302/task_03/doc/1.png new file mode 100644 index 000000000..23bcff185 Binary files /dev/null and b/trunk/II02302/task_03/doc/1.png differ diff --git a/trunk/II02302/task_03/doc/2.png b/trunk/II02302/task_03/doc/2.png new file mode 100644 index 000000000..447ff2b0e Binary files /dev/null and b/trunk/II02302/task_03/doc/2.png differ diff --git a/trunk/II02302/task_03/doc/3.png b/trunk/II02302/task_03/doc/3.png new file mode 100644 index 000000000..3a2d2a6c5 Binary files /dev/null and b/trunk/II02302/task_03/doc/3.png differ diff --git a/trunk/II02302/task_03/doc/4.png b/trunk/II02302/task_03/doc/4.png new file mode 100644 index 000000000..04f270d7d Binary files /dev/null and b/trunk/II02302/task_03/doc/4.png differ diff --git a/trunk/II02302/task_03/doc/5.png b/trunk/II02302/task_03/doc/5.png new file mode 100644 index 000000000..cdcf2cffa Binary files /dev/null and b/trunk/II02302/task_03/doc/5.png differ diff --git a/trunk/II02302/task_03/doc/6.png b/trunk/II02302/task_03/doc/6.png new file mode 100644 index 000000000..b2df0b08f Binary files /dev/null and b/trunk/II02302/task_03/doc/6.png differ diff --git a/trunk/II02302/task_03/doc/7.png b/trunk/II02302/task_03/doc/7.png new file mode 100644 index 000000000..29a560735 Binary files /dev/null and b/trunk/II02302/task_03/doc/7.png differ diff --git a/trunk/II02302/task_03/doc/8.png b/trunk/II02302/task_03/doc/8.png new file mode 100644 index 000000000..3fd86646e Binary files /dev/null and b/trunk/II02302/task_03/doc/8.png differ diff --git a/trunk/II02302/task_03/doc/report.md b/trunk/II02302/task_03/doc/report.md new file mode 100644 index 000000000..fffcc59b9 --- /dev/null +++ b/trunk/II02302/task_03/doc/report.md @@ -0,0 +1,62 @@ +

Министерство образования Республики Беларусь

+

Учреждение образования

+

«Брестский государственный технический университет»

+

Кафедра ИИТ

+




+

Лабораторная работа №3

+

За третий семестр

+

По дисциплине: «Общая теория интеллектуальных систем»

+

Тема: «Разработка редакторов графов»

+




+

Выполнила:

+

Студентка 2 курса

+

Группы ИИ-23

+

Волкогон Н.И.

+

+

Проверил:

+

Иванюк Д.С.

+ +

Брест 2023
+ +-- +# В работе было реализованно: # +1. Разработка и реализация программного продукта позволяющего +редактировать графовые конструкции различных видов и производить над +ними различные действия. + +2. Редактор позволяет: + a) одновременно работать с несколькими графами (MDI); + b) **[\*]** выделение одновременно нескольких элементов графа, копирование +выделенного фрагмента в clipboard и восстановление из него; + c) задавать имена графам; + d) сохранять и восстанавливать граф во внутреннем формате программы; + e) экспортировать и импортировать граф в текстовый формат (описание +см. ниже); + f) создавать, удалять, именовать, переименовывать, перемещать узлы; + g) создавать неориентированные дуги, удалять дуги; + h) добавлять, удалять и редактировать содержимое узла (содержимое в +виде текста и ссылки на файл); + i) задавать цвет дуги и узла, образ узла; + j) **[\*]** создавать и отображать петли; + k) **[\*]** создавать и отображать кратные дуги. + +3. Программный продукт позволяет выполнять следующие операции: + a) выводить информацию о графе; + b) поиск всех путей (маршрутов) между двумя узлами и кратчайших; + c) вычисление расстояния между двумя узлами; + d) **[\*]** раскраска графа; + e) нахождения эйлеровых циклов. + +4. Отчет по выполненной лабораторной работе в .md формате (readme.md). Разместить его в следующем каталоге: **trunk\ii0xxyy\task_03\doc** (где **xx** - номер группы, **yy** - номер студента, например **ii02302**). + +5. Исходный код разработанной программы разместить в каталоге: **trunk\ii0xxyy\task_03\src**. +nk\ii0xxyy\task_04\doc. + +![Снимок экрана (1)](1.png) +![Снимок экрана (2)](2.png) +![Снимок экрана (3)](3.png) +![Снимок экрана (4)](4.png) +![Снимок экрана (5)](5.png) +![Снимок экрана (6)](6.png) +![Снимок экрана (7)](7.png) +![Снимок экрана (8)](8.png) diff --git a/trunk/II02302/task_03/src/CMakeLists.txt b/trunk/II02302/task_03/src/CMakeLists.txt new file mode 100644 index 000000000..fe78eaf51 --- /dev/null +++ b/trunk/II02302/task_03/src/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.5) + +project(otis_3) + +set(SOURCES + Source.cpp + library.cpp +) + +set(HEADERS + header.h +) + +add_executable(OTIS_03 ${SOURCES} ${HEADERS}) diff --git a/trunk/II02302/task_03/src/Source.cpp b/trunk/II02302/task_03/src/Source.cpp new file mode 100644 index 000000000..6e59ec3d0 --- /dev/null +++ b/trunk/II02302/task_03/src/Source.cpp @@ -0,0 +1,172 @@ +#include +#include +#include +#include "..\Graph_lib\Header.h"; + +using namespace std; + +int main() +{ + string str; + cout << "Enter file's name: "; + cin >> str; + ifstream fin(str); + int vertexCount, edgesCount; + fin >> vertexCount >> edgesCount; + + int** matrix = new int* [vertexCount]; + for (int i = 0; i < vertexCount; i++) + matrix[i] = new int[vertexCount]; + vector used(vertexCount); + int res; + int* path = new int[vertexCount]; + int* f = new int[vertexCount]; + //menu + int go; + do + { + cout << "1. Fill Matrix\n"; + cout << "2. Paint Matrix\n"; + cout << "\nlab1\n3. bfs\n"; + cout << "4. dfs\n"; + cout << "\nlab2\n5. Gamilton\n"; + cout << "6. Euler\n"; + cout << "\nlab3\n7. Dijkstra\n"; + cout << "8. Floyd\n"; + cout << "\nlab5\n9. Prim\n"; + cout << "10.Kruskal\n"; + cout << "\nlab4\n11. Kali\n"; + cout << "12. Permutation\n"; + cout << "\nlab6\n13. Strong connectivity\n"; + cout << "14.Biconnected Components\n"; + cout << "0. End\n"; + cout << "Choise: "; + cin >> go; + switch (go) + { + case 1://Fill + system("cls"); + Fill_Matrix(matrix, vertexCount, edgesCount, str); + break; + + case 2://Paint + system("cls"); + Paint_Matrix(matrix, vertexCount); + break; + + case 3://bfs + system("cls"); + res = 0; + for (int i = 0; i < vertexCount; i++) + if (!used[i]) + { + res++; + bfs(matrix, vertexCount, i, used); + } + cout << endl << "Number of connectivity components: " << res << endl; + break; + + case 4://dfs + system("cls"); + res = 0; + for (int i = 0; i < vertexCount; i++) + if (!used[i]) + { + res++; + dfs(matrix, vertexCount, i, used); + } + cout << endl << "Number of connectivity components: " << res << endl; + break; + + case 5://Gamilton + system("cls"); + int v0; + cout << "Enter firts vertex: "; + cin >> v0; + v0--; + for (int i = 0; i < vertexCount; i++) + f[i] = -1; + f[v0] = v0; + path[0] = v0; + if (Gamilton(matrix, path, f, vertexCount, 1, v0)) + { + Print_Path(path, vertexCount); + cout << endl; + } + else cout << "No results\n"; + break; + + case 6://Euler + system("cls"); + + if ( res > 1) + cout << "Wrong\n"; + else + { + + int check = 0; + int buf; + for (int i = 0; i < vertexCount; i++) + { + buf = 0; + for (int j = 0; j < vertexCount; j++) + buf += matrix[i][j]; + if (buf % 2) + check++; + } + if (check) + cout << "Wrong\n"; + else + { + + vectorpath; + Euler(matrix, path, vertexCount); + for (int i = 1; i < path.size(); i++) + cout << path[i] + 1 << " "; + cout << endl; + break; + } + } + + case 7: + system("cls"); + Dijkstra(matrix,vertexCount); + break; + + case 8: + system("cls"); + Floyd(matrix, vertexCount); + break; + + case 9: + system("cls"); + Prim(matrix, vertexCount); + break; + + case 10: + system("cls"); + main_kruskal(matrix,vertexCount, edgesCount,str); + break; + + case 11: + system("cls"); + Kali(); + break + ; + case 12: + system("cls"); + Permutation(str); + break; + + case 13: + system("cls"); + StrongConnectedComponents(matrix, vertexCount); + break; + case 14: + system("cls"); + FindArtPointsAndBridges(matrix, vertexCount); + break; + } + } while (go); + +} diff --git a/trunk/II02302/task_03/src/header.h b/trunk/II02302/task_03/src/header.h new file mode 100644 index 000000000..65eae5f58 --- /dev/null +++ b/trunk/II02302/task_03/src/header.h @@ -0,0 +1,21 @@ +using namespace std; +#pragma once +void dfs(int**, int, int, vector&); +void bfs(int**, int, int, vector&); +void Fill_Matrix(int**&, int, int, string); +void Paint_Matrix(int**&, int); +bool Gamilton(int**&, int*&, int*&, int, int, int); +void Print_Path(int*&, int); +void Euler(int**&, vector&, int); +void Dijkstra(int**&, int); +void Floyd(int**&, int); +void Prim(int**&, int); +int parent(int*, int); +void union_find(int*, int, int); +void Kruskal(pair>*, int*, int**&, int, int); +void main_kruskal(int**&, int, int, string); +void Kali(); +void Permutation(string); +void StrongConnectedComponents(int**&, int); +//void findBiconnectedComponents(int**&, int); +void FindArtPointsAndBridges(int**&, int); \ No newline at end of file diff --git a/trunk/II02302/task_03/src/library.cpp b/trunk/II02302/task_03/src/library.cpp new file mode 100644 index 000000000..a2257bd9d --- /dev/null +++ b/trunk/II02302/task_03/src/library.cpp @@ -0,0 +1,712 @@ +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +const int inf = 10000; + +void dfs(int** matrix, int vertexCount, int v, vector& used)//â ãëóáèíó +{ + cout << endl; + stack stack; + stack.push(v); + while (!stack.empty()) + { + v = stack.top(); + stack.pop(); + if (used[v]) + continue; + used[v] = true; + cout << v + 1; + for (int i = 0; i < vertexCount; i++) + if (!used[i] && matrix[v][i]) + stack.push(i); + } +} + +void bfs(int** matrix, int vertexCount, int v, vector& used)//â øèðèíó +{ + cout << endl; + queue q; + q.push(v); + used[v] = true; + while (!q.empty()) + { + int u = q.front(); + q.pop(); + cout << u + 1 << " "; + for (int i = 0; i < vertexCount; i++) + { + if (!used[i] && matrix[u][i]) + { + q.push(i); + used[i] = true; + } + } + } +} + +void Fill_Matrix(int**& matrix, int vertexCount, int edgesCount, string str) +{ + ifstream fin(str); + for (int i = 0; i < vertexCount; i++) + for (int j = 0; j < vertexCount; j++) + matrix[i][j] = false; + int buf1, buf; + fin >> buf >> buf1; + for (int i = 0; i < edgesCount; i++) + { + int a, b, c; + fin >> a >> b >> c; + cout << a << " -> " << b << endl; + a--; b--; + matrix[a][b] = c; + //matrix[b][a] = c; + } +} + +void Paint_Matrix(int**& matrix, int vertexCount) +{ + for (int i = 0; i < vertexCount; i++) + { + for (int j = 0; j < vertexCount; j++) + cout << matrix[i][j] << " "; + cout << endl; + } +} + +void Print_Path(int*& path, int vetexCount) +{ + for (int i = 0; i < vetexCount; i++) + cout << path[i] + 1 << " "; + cout << path[0] + 1; +} + +bool Gamilton(int**& matrix, int*& path,int*& f, int vertexCount, int k, int v0)//íà÷àëüíàÿ âåðøèíà +{ + bool res = false; + for (int i = 0; i < vertexCount; i++) + { + if (matrix[i][path[k - 1]]) + { + if (k == vertexCount && i == v0) + res = true; + else + if (f[i] == -1) + { + f[i] = k; + path[k] = i; + res = Gamilton(matrix, path, f, vertexCount, k + 1, v0); + if (!res) f[i] = -1; + } + } + else continue; + } + return res; +} + +void Euler(int**& matrix, vector& path, int vertexCount)//íà÷àëüíàÿ âåðøèíà +{ + int* degree = new int[vertexCount]; + for (int i = 0; i < vertexCount; i++) + degree[i] = NULL; + for (int i = 0; i < vertexCount; i++) + for (int j = 0; j < vertexCount; j++) + if (matrix[i][j]) + degree[i]++; + stack st; + st.push(0); + path.push_back(0); + while (!st.empty()) + { + int v = st.top(); + if (degree[v] == NULL) + { + st.pop(); + path.push_back(v); + } + else + { + for(int i = 0; i < vertexCount ;i++) + if (matrix[v][i]) + { + matrix[v][i] = NULL; + matrix[i][v] = NULL; + degree[v]--; + degree[i]--; + st.push(i); + break; + } + } + } +} + +void Dijkstra(int**& matrix, int vertexCount) +{ + for (int i = 0; i < vertexCount; i++) + for (int j = 0; j < vertexCount; j++) + { + if (matrix[i][j] == NULL) + matrix[i][j] = inf; + } + vector dist(vertexCount, inf); + vector used(vertexCount, false); + vector prev(vertexCount, -1); + + dist[0] = NULL; + used[0] = true; + prev[0] = NULL; + + for (int i = 0; i < vertexCount; i++) + if (matrix[0][i] <= dist[i]) + { + dist[i] = matrix[0][i]; + prev[i] = NULL; + } + + for (int i = 0; i < vertexCount - 1; i++) + { + int min = inf; + for (int j = 0; j < dist.size(); j++) + if (min > dist[j] && !used[j]) + min = j; + int minDist = dist[min]; + used[min] = true; + + for (int j = 0; j < vertexCount; j++) + { + if (!used[j] && dist[j] > matrix[min][j] + minDist && minDist>0) + { + dist[j] = matrix[min][j] + minDist; + prev[j] = min; + } + } + } + for (int i = 0; i < vertexCount; i++) { + cout << i + 1 << "\t" << dist[i] << "\t" << prev[i] + 1 << endl; + } + +} + +void Floyd(int**& matrix, int vertexCount) +{ + + int** temp = matrix; + for(int i = 0; i < vertexCount; i++) + for (int j = 0; j < vertexCount; j++) + { + if (i == j) temp[i][j] = NULL; + else if (matrix[i][j]) temp[i][j] = matrix[i][j]; + else temp[i][j] = inf; + } + for (int k = 0; k < vertexCount; k++) + for (int i = 0; i < vertexCount; i++) + for (int j = 0; j < vertexCount; j++) + if (temp[i][j] > temp[i][k] + temp[k][j]) + temp[i][j] = temp[i][k] + temp[k][j]; + for (int i = 0; i < vertexCount; i++) + { + for (int j = 0; j < vertexCount; j++) + cout << temp[i][j] << "\t"; + cout << endl; + } +} + +void Prim(int**& matrix,int vertexCount) +{ + bool* selected = new bool[vertexCount]; + for (int i = 0; i < vertexCount; i++) + selected[i] = false; + selected[0] = true; + int search = NULL; + int column = 0, line = 0; + int weight = NULL; + while (search < vertexCount - 1) + { + int min = inf; + for(int i = 0; i < vertexCount; i++) + if(selected[i]) + for(int j = 0; j < vertexCount; j++) + if(!selected[j] && matrix[i][j]) + if (min > matrix[i][j]) + { + min = matrix[i][j]; + line = i; + column = j; + } + cout << line + 1 << " -> " << column + 1 << " = " << min; + search++; + weight += min; + cout << endl; + selected[column] = true; + } + cout << "Total weight is " << weight << endl; +} + +int parent(int* root, int a) +{ + while (root[a] != a) + { + root[a] = root[root[a]]; + a = root[a]; + } + return a; +} + +void union_find(int* root, int a, int b) +{ + int d = parent(root, a); + int e = parent(root, b); + root[d] = root[e]; +} + +int Kruskal(pair>* p, int* root, int**& matrix, int vertexCount, int edgesCount) +{ + int mincost = NULL; + + for (int i = 0; i < edgesCount; i++) + { + int a = p[i].second.first; + int b = p[i].second.second; + int cost = p[i].first; + if (parent(root, a) != parent(root, b)) + { + mincost += cost; + union_find(root, a, b); + cout << a + 1 << " -> " << b + 1 << " " << cost << endl; + } + } + return mincost; +} + +void main_kruskal(int**& matrix, int vertexCount, int edgesCount, string str) +{ + pair> p[inf]; + int root[inf]; + int mincost; + for (int i = 0; i < inf; i++) + root[i] = i; + ifstream fin(str); + int buf1, buf2; + fin >> buf1 >> buf2; + for (int i = 0; i < edgesCount; i++) + { + int a, b, c; + fin >> a >> b >> c; + a--; b--; + p[i] = make_pair(c, make_pair(a, b)); + } + sort(p, p + edgesCount); + mincost = Kruskal(p, root, matrix, vertexCount, edgesCount); + cout << mincost << endl; +} + +void f(vector& used, vector& perm, vector>& transposition, int i, int& n) +{ + vector res; + while (!used[i]) + { + res.push_back(perm[i]); + used[i] = true; + i = perm[i]; + } + if (!res.empty()) + { + cout << "( "; + for (int i = 0; i < res.size() - 1; i++) + cout << res[i] + 1 << " , "; + + cout << res.back() + 1 << " )"; + + for (int i = 1; i < res.size(); i++) + { + transposition[n][0] = res[0] + 1; + transposition[n][1] = res[i] + 1; + n++; + } + } +} + +void Permutation(string str) +{ + vector perm(6); + ifstream fin(str); + for (int i = 0; i < 6; i++) + { + fin >> perm[i]; + perm[i]--; + } + for (int i = 0; i < 6; i++) + cout << i + 1 << " "; + cout << endl; + for (int i = 0; i < 6; i++) + cout << perm[i] + 1 << " "; + + cout << endl; + int n = 0; + vector> transposition(4,vector (2)); + vector used(6); + for(int i=0; i<6; i++) + f(used, perm,transposition, i, n); + cout << endl; + for (int i = 0; i < transposition.size(); i++) + cout <<"{ " << transposition[i][0] << " , " << transposition[i][1] << " } "; + cout << endl; + cout << "Degree of permutation is " << perm.size() << endl; + int perm_degree = 0; + for (int i = 0; i < perm.size(); i++) + for (int j = i + 1; j < perm.size(); j++) + if (perm[i] > perm[j]) + perm_degree++; + cout << "Number of inversions is " << perm_degree << endl; + if (perm_degree % 2) + cout << "Permutation is odd\n"; + else cout << "Permutation is even\n"; + + +} + +void table_kali(vector& mass, int& neutral) +{ + for (int i = 0; i < mass.size(); i++) + { + for (int j = 0; j < mass.size(); j++) + cout << (mass[i] * mass[j]) % 7 << "\t"; + cout << endl; + } +} + +void Kali() +{ + int neutral = NULL; + vector kali(6); + for (int i = 0; i < 6; i++) + kali[i] = i + 1; + for (int i = 0; i < 6; i++) + for (int j = 0; j < 6; j++) + if (kali[i] * kali[j] % 7 == kali[j]) + neutral = kali[i]; + /*for (int i = 0; i < 6; i++) + { + for (int j = 0; j < 6; j++) + { + if (kali[i] * kali[j] == kali[j]) buf++; + cout << (kali[i] * kali[j]) % 7 << "\t"; + } + if (buf) + { + neutral = kali[i]; + buf = -1; + } + cout << endl; + }*/ + + table_kali(kali, neutral); + + cout << "Neutral element is " << neutral << endl; + cout << "Reverse elements:\n"; + for (int i = 0; i < 6; i++) + for (int j = 0; j < 6; j++) + if (kali[i] * kali[j] % 7 == neutral) + cout << "for " << kali[i] << " is " << kali[j] << endl; + + vector undergroup; + + + for (int i = 0; i < 6; i++) + { + vector group; + int p = 0; + int res; + res = pow(kali[i], 2); + res %= 7; + group.push_back(res); + while (p < 6) + { + p++; + if (res == neutral) + { + cout << "Degree for " << kali[i] << " is " << p << endl; + if (p == 5) + cout << "Element " << kali[i] << " generates a cycle group " << endl; + else cout << "Element " << kali[i] << " generates a group " << endl; + if (i == 1) { + undergroup.push_back(kali[i]); + cout << "{ " << kali[i] << " , "; + for (int i = 0; i < group.size() - 1; i++) + { + cout << group[i] << " , "; + undergroup.push_back(group[i]); + } + undergroup.push_back(group.back()); + cout << group.back() << " }" << endl; + break; + } + else + { + cout << "{ " << kali[i] << " , "; + for (int i = 0; i < group.size() - 1; i++) + cout << group[i] << " , "; + cout << group.back() << " }" << endl; + break; + } + } + else + { + res *= kali[i]; + res %= 7; + group.push_back(res); + } + } + } + + cout << endl; + sort(undergroup.begin(), undergroup.end()); + cout << "Kali's table for H2" << endl; + table_kali(undergroup, neutral); + + +} + +//void findArticulationPoints(int**& matrix, int vertexCount, int v, int& time, vectorused, vectordisc, vectorlow, stack> st) +//{ +// disc[v] = low[v] = ++time; +// used[v] = true; +// +// for (int i = 0; i < vertexCount; i++) +// { +// if (!matrix[v][i]) +// continue; +// if (!used[v]) +// { +// st.push(make_pair(v, i)); +// findArticulationPoints(matrix, vertexCount, i, time, used, disc, low, st); +// low[v] = min(low[i], low[v]); +// +// if (low[i] >= disc[v]) +// { +// cout << "Íîâàÿ êîìïîíåíòà äâóñâÿçíîñòè: "; +// while (st.top() != make_pair(v, i)) +// { +// cout << st.top().first << " -- " << st.top().second << endl; +// st.pop(); +// } +// cout << st.top().first << " -- " << st.top().second << endl; +// st.pop(); +// +// } +// +// } +// else if (i != st.top().first && disc[i] < low[v]) +// { +// low[v] = disc[i]; +// st.push(make_pair(v,i)); +// } +// } +//} +// +//void findBiconnectedComponents(int**& matrix, int vertexCount) +//{ +// vector used(vertexCount, false); +// vector disc(vertexCount, false); +// vector low(vertexCount, false); +// stack> st; +// int time = 0; +// +// for (int i = 0; i < vertexCount; i++) +// if (!used[i]) +// findArticulationPoints(matrix, vertexCount, i, time, used, disc, low, st); +// +//} +// +void transposition(int**& matrix, int vertexcount, vector>& transpon) +{ + for (int i = 0; i < vertexcount; i++) + for (int j = 0; j < vertexcount; j++) + transpon[i][j] = matrix[j][i]; +} + +void fillorder(int**& matrix, int vertexcount, int v, vector& visited, stack & st) +{ + visited[v] = true; + for (int i = 0; i < vertexcount; i++) + if (matrix[v][i] && !visited[i]) + fillorder(matrix, vertexcount, i, visited, st); + st.push(v); +} + +void dfs1(int**& matrix, int vertexcount, int v, vector& visited) +{ + visited[v] = true; + cout << v + 1 << " "; + for (int i = 0; i < vertexcount; i++) + if (matrix[v][i] && !visited[i]) + dfs1(matrix, vertexcount, i, visited); +} + +void StrongConnectedComponents(int**& matrix, int vertexcount) +{ + stack st; + vector visited(vertexcount, false); + for (int i = 0; i < vertexcount; i++) + if (!visited[i]) + fillorder(matrix, vertexcount, i, visited, st); + + vector> transpon(vertexcount, vector(vertexcount, false)); + + transposition(matrix, vertexcount, transpon); + + visited.assign(vertexcount, false); + + while (!st.empty()) + { + int v = st.top(); + st.pop(); + + if (!visited[v]) + { + dfs1(matrix, vertexcount, v, visited); + cout << endl; + } + } +} + +bool CheckForPath(int**& matrix, int vertexCount, int start, vector& inPath) +{ + int check = 0; + for (int i = 0; i < vertexCount; i++) + if (matrix[start][i] && !inPath[i]) + check++; + if (!check) + return false; + return true; +} + +void FillStack(int**& matrix, int vertexCount,stack& mainStack) +{ + stack tempStack; + vector isVisited(vertexCount, false); + vector path; + vector inPath(vertexCount, false); + + tempStack.push(NULL); + + while (!tempStack.empty()) + { + int top = tempStack.top(); + path.push_back(top); + tempStack.pop(); + if (!isVisited[top]) + { + isVisited[top] = true; + int check = 0; + for (int i = 0; i < vertexCount; i++) + if (matrix[top][i] && !isVisited[i]) + { + tempStack.push(i); + check++; + } + if (!check) + { + mainStack.push(top); + inPath[top] = true; + + for (int i = 2; i < path.size() + 1; i++) + { + int start = path[path.size() - i]; + if (!inPath[start] && !CheckForPath(matrix, vertexCount, start, inPath)) + { + mainStack.push(start); + inPath[start] = true; + } + } + } + } + } +} + +void PrintSSCs(int**& matrix, int vertexCount, stack& mainStack) +{ + vector isVisited(vertexCount, false); + while (!mainStack.empty()) + { + int top = mainStack.top(); + mainStack.pop(); + + if (!isVisited[top]) + { + isVisited[top] = true; + stack tempStack; + tempStack.push(top); + + while (!tempStack.empty()) + { + int ttop = tempStack.top(); + tempStack.pop(); + for (int i = 0; i < vertexCount; i++) + { + if (matrix[i][ttop] && !isVisited[i]) + { + tempStack.push(i); + isVisited[i] = true; + } + } + } + } + } +} + +void TarjanDFS(int**& matrix, int vertexCount, int u, vector& disc, vector& low, vector& parent, vector& articulationPoint, vector >& bridge) +{ + static int time = 0; + disc[u] = low[u] = time; + time++; + int children = 0; + + for (int v = 0; v < vertexCount; v++) + { + if (disc[v] == -1 && matrix[u][v]) + { + children++; + parent[v] = u; + TarjanDFS(matrix, vertexCount, v, disc, low, parent, articulationPoint, bridge); + low[u] = min(low[u], low[v]); + + if (parent[u] == -1 and children > 1) + articulationPoint[u] = true; + + if (parent[u] != -1 and low[v] >= disc[u]) + articulationPoint[u] = true; + + if (low[v] > disc[u]) + bridge.push_back({ u, v }); + } + else if (v != parent[u] && matrix[u][v]) + low[u] = min(low[u], disc[v]); + } +} + +void FindArtPointsAndBridges(int**& matrix, int vertexCount) +{ + vector disc(vertexCount, -1), low(vertexCount, -1), parent(vertexCount, -1); + vector articulationPoint(vertexCount, false); + vector> bridge; + + for (int i = 0; i < vertexCount; i++) + if (disc[i] == -1) + TarjanDFS(matrix, vertexCount, i, disc, low, parent, articulationPoint, bridge); + cout << "Articulation points: "; + for (int i = 0; i < vertexCount; i++) + if (articulationPoint[i]) + cout << i + 1 << " "; + cout << "\nBridges: "; + for(int i=0;i