-
Notifications
You must be signed in to change notification settings - Fork 22
Pronin Arkadiy's Tasks #29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
a821fe1
00e8569
395130f
d9620cc
e2597ef
e144bf9
77eb5dd
52a527f
5442828
4e9dc53
473a523
367b32e
dec3df3
7e77eed
fd9bea4
4aea517
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,197 @@ | ||||||||||
#include "graph.hpp" | ||||||||||
|
||||||||||
#include <iostream> | ||||||||||
#include <stdexcept> | ||||||||||
|
||||||||||
#define UNREACHABLE (-1) | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: macro 'UNREACHABLE' defines an integral constant; prefer an enum instead [cppcoreguidelines-macro-to-enum] #define UNREACHABLE (-1)
^ |
||||||||||
|
||||||||||
EchoPr marked this conversation as resolved.
Show resolved
Hide resolved
EchoPr marked this conversation as resolved.
Show resolved
Hide resolved
EchoPr marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: replace macro with enum [cppcoreguidelines-macro-to-enum]
Suggested change
|
||||||||||
using namespace algo; | ||||||||||
|
||||||||||
Graph::Graph(int v, int e) { | ||||||||||
if (v <= 0) | ||||||||||
throw std::invalid_argument( | ||||||||||
"Number of vertices must be greater than zero."); | ||||||||||
|
||||||||||
vertexes_num = v; | ||||||||||
edges_num = e; | ||||||||||
adjList.resize(v); | ||||||||||
} | ||||||||||
|
||||||||||
Graph::Graph(int v, int e, bool directed) { | ||||||||||
if (v <= 0) | ||||||||||
throw std::invalid_argument( | ||||||||||
"Number of vertices must be greater than zero."); | ||||||||||
|
||||||||||
vertexes_num = v; | ||||||||||
edges_num = e; | ||||||||||
is_directed = directed; | ||||||||||
adjList.resize(v); | ||||||||||
} | ||||||||||
|
||||||||||
void Graph::AddEdge(int u, int v, int weight) { | ||||||||||
if (u < 1 || u > vertexes_num || v < 1 || v > vertexes_num) { | ||||||||||
throw std::out_of_range("Vertex out of bounds in addEdge."); | ||||||||||
} | ||||||||||
|
||||||||||
adjList[u - 1].emplace_back(v - 1, weight); | ||||||||||
if (!is_directed) adjList[v - 1].emplace_back(u - 1, weight); | ||||||||||
|
||||||||||
edges_num++; | ||||||||||
} | ||||||||||
|
||||||||||
int Graph::GetVertexesNum() { | ||||||||||
if (vertexes_num <= 0) | ||||||||||
throw std::runtime_error("Graph is not properly initialized."); | ||||||||||
return vertexes_num; | ||||||||||
} | ||||||||||
|
||||||||||
int Graph::GetEdgesNum() { return edges_num; } | ||||||||||
|
||||||||||
const AdjacencyList Graph::GetAdjList() { return adjList; } | ||||||||||
|
||||||||||
void Graph::PrintGraph() const { | ||||||||||
if (vertexes_num == 0) { | ||||||||||
std::cerr << "Error: Graph is empty." << std::endl; | ||||||||||
EchoPr marked this conversation as resolved.
Show resolved
Hide resolved
EchoPr marked this conversation as resolved.
Show resolved
Hide resolved
EchoPr marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: do not use 'std::endl' with streams; use '\n' instead [performance-avoid-endl]
Suggested change
|
||||||||||
return; | ||||||||||
} | ||||||||||
|
||||||||||
for (int i = 0; i < vertexes_num; i++) { | ||||||||||
if (adjList[i].empty()) continue; | ||||||||||
|
||||||||||
std::cout << "Node " << i + 1 << ": "; | ||||||||||
|
||||||||||
for (const auto& [neighbor, weight] : adjList[i]) { | ||||||||||
std::cout << "(" << neighbor + 1 << ", " << weight << ") "; | ||||||||||
} | ||||||||||
std::cout << '\n'; | ||||||||||
EchoPr marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
} | ||||||||||
} | ||||||||||
|
||||||||||
std::vector<std::pair<int, int>> Graph::GetNeighbours(int v) { | ||||||||||
if (v < 0 || v >= vertexes_num) { | ||||||||||
throw std::out_of_range("Vertex index out of bounds in getNeighbours."); | ||||||||||
} | ||||||||||
return adjList[v]; | ||||||||||
} | ||||||||||
|
||||||||||
void Graph::TopSort(int v, std::vector<bool>& visited, std::vector<int>& way) { | ||||||||||
if (visited[v]) return; | ||||||||||
visited[v] = true; | ||||||||||
way.push_back(v); | ||||||||||
|
||||||||||
for (auto [u, w] : GetNeighbours(v)) { | ||||||||||
if (!visited[u]) { | ||||||||||
TopSort(u, visited, way); | ||||||||||
} | ||||||||||
} | ||||||||||
} | ||||||||||
|
||||||||||
std::vector<int> Graph::TopologicalSort(int start) { | ||||||||||
if (vertexes_num == 0) { | ||||||||||
std::cerr | ||||||||||
<< "Error: Graph is empty, topological sort cannot be performed.\n"; | ||||||||||
return {}; | ||||||||||
} | ||||||||||
|
||||||||||
std::vector<int> way; | ||||||||||
std::vector<bool> visited(GetVertexesNum(), false); | ||||||||||
|
||||||||||
TopSort(start, visited, way); | ||||||||||
|
||||||||||
if (way.size() < vertexes_num) | ||||||||||
throw std::invalid_argument("Graph is disconnected."); | ||||||||||
|
||||||||||
return way; | ||||||||||
} | ||||||||||
|
||||||||||
std::vector<std::pair<int, int>> Graph::GetBridges() { | ||||||||||
std::vector<int> tin(vertexes_num, -1); | ||||||||||
std::vector<int> low(vertexes_num, -1); | ||||||||||
std::vector<bool> visited(vertexes_num, false); | ||||||||||
std::vector<std::pair<int, int>> bridges; | ||||||||||
int timer = 0; | ||||||||||
|
||||||||||
for (int i = 0; i < vertexes_num; i++) { | ||||||||||
if (!visited[i]) { | ||||||||||
DfsBridges(i, -1, tin, low, visited, timer, bridges); | ||||||||||
} | ||||||||||
} | ||||||||||
|
||||||||||
return bridges; | ||||||||||
} | ||||||||||
|
||||||||||
void Graph::DfsBridges(int v, int parent, std::vector<int>& tin, | ||||||||||
std::vector<int>& low, std::vector<bool>& visited, | ||||||||||
int& timer, std::vector<std::pair<int, int>>& bridges) { | ||||||||||
visited[v] = true; | ||||||||||
tin[v] = low[v] = timer++; | ||||||||||
|
||||||||||
for (auto [u, _] : adjList[v]) { | ||||||||||
if (u == parent) continue; | ||||||||||
|
||||||||||
if (!visited[u]) { | ||||||||||
DfsBridges(u, v, tin, low, visited, timer, bridges); | ||||||||||
low[v] = std::min(low[v], low[u]); | ||||||||||
|
||||||||||
if (low[u] > tin[v]) { | ||||||||||
bridges.emplace_back(v + 1, u + 1); // Добавляем мост (нумерация с 1) | ||||||||||
} | ||||||||||
} else { | ||||||||||
low[v] = std::min(low[v], tin[u]); | ||||||||||
} | ||||||||||
} | ||||||||||
} | ||||||||||
|
||||||||||
std::vector<int> Graph::GetArticulationPoints() { | ||||||||||
std::vector<int> tin(vertexes_num, -1); | ||||||||||
std::vector<int> low(vertexes_num, -1); | ||||||||||
std::vector<bool> visited(vertexes_num, false); | ||||||||||
std::vector<bool> isArticulationPoint(vertexes_num, false); | ||||||||||
int timer = 0; | ||||||||||
|
||||||||||
for (int i = 0; i < vertexes_num; i++) { | ||||||||||
if (!visited[i]) { | ||||||||||
DfsArticulation(i, -1, tin, low, visited, timer, isArticulationPoint); | ||||||||||
} | ||||||||||
} | ||||||||||
|
||||||||||
std::vector<int> articulationPoints; | ||||||||||
for (int i = 0; i < vertexes_num; i++) { | ||||||||||
if (isArticulationPoint[i]) { | ||||||||||
articulationPoints.push_back(i + 1); // Нумерация с 1 | ||||||||||
} | ||||||||||
} | ||||||||||
|
||||||||||
return articulationPoints; | ||||||||||
} | ||||||||||
|
||||||||||
void Graph::DfsArticulation(int v, int parent, std::vector<int>& tin, | ||||||||||
std::vector<int>& low, std::vector<bool>& visited, | ||||||||||
int& timer, | ||||||||||
std::vector<bool>& isArticulationPoint) { | ||||||||||
visited[v] = true; | ||||||||||
tin[v] = low[v] = timer++; | ||||||||||
int children = 0; | ||||||||||
|
||||||||||
for (auto [u, _] : adjList[v]) { | ||||||||||
if (u == parent) continue; | ||||||||||
|
||||||||||
if (!visited[u]) { | ||||||||||
children++; | ||||||||||
DfsArticulation(u, v, tin, low, visited, timer, isArticulationPoint); | ||||||||||
low[v] = std::min(low[v], low[u]); | ||||||||||
|
||||||||||
// Условие для точки сочленения | ||||||||||
if (parent != -1 && low[u] >= tin[v]) { | ||||||||||
isArticulationPoint[v] = true; | ||||||||||
} | ||||||||||
} else { | ||||||||||
low[v] = std::min(low[v], tin[u]); | ||||||||||
} | ||||||||||
} | ||||||||||
|
||||||||||
// Отдельное условие для корня | ||||||||||
if (parent == -1 && children > 1) { | ||||||||||
isArticulationPoint[v] = true; | ||||||||||
} | ||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#pragma once | ||
|
||
#ifndef GRAPH_HPP | ||
#define GRAPH_HPP | ||
|
||
#include <vector> | ||
|
||
using AdjacencyList = std::vector<std::vector<std::pair<int, int>>>; | ||
|
||
namespace algo { | ||
class Graph { | ||
public: | ||
Graph(int v, int e); | ||
|
||
Graph(int v, int e, bool directed); | ||
|
||
void AddEdge(int, int, int); | ||
|
||
int GetVertexesNum(); | ||
int GetEdgesNum(); | ||
const AdjacencyList GetAdjList(); | ||
|
||
std::vector<std::pair<int, int>> GetNeighbours(int); | ||
|
||
bool HasEdge(int, int) const; | ||
|
||
void PrintGraph() const; | ||
|
||
std::vector<int> TopologicalSort(int); | ||
|
||
std::vector<std::pair<int, int>> GetBridges(); | ||
std::vector<int> GetArticulationPoints(); | ||
|
||
private: | ||
int vertexes_num = 0; | ||
int edges_num = 0; | ||
bool is_directed = false; | ||
|
||
AdjacencyList adjList; | ||
|
||
void TopSort(int, std::vector<bool>&, std::vector<int>&); | ||
|
||
void DfsBridges(int, int, std::vector<int>&, std::vector<int>&, | ||
std::vector<bool>&, int&, std::vector<std::pair<int, int>>&); | ||
|
||
void DfsArticulation(int, int, std::vector<int>&, std::vector<int>&, | ||
std::vector<bool>&, int&, std::vector<bool>&); | ||
}; | ||
}; // namespace algo | ||
|
||
#endif // GRAPH_HPP |
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -1 +1,44 @@ | ||||||||||
#include "util.hpp" | ||||||||||
|
||||||||||
#include <climits> | ||||||||||
#include <queue> | ||||||||||
#include <utility> | ||||||||||
#include <vector> | ||||||||||
|
||||||||||
#include "graph.hpp" | ||||||||||
|
||||||||||
using namespace std; | ||||||||||
|
||||||||||
vector<int> FindWays(algo::Graph graph, int start) { | ||||||||||
vector<int> vis(graph.GetVertexesNum()); | ||||||||||
vector<int> dst(graph.GetVertexesNum(), INT_MAX); | ||||||||||
|
||||||||||
dst[start - 1] = 0; | ||||||||||
|
||||||||||
Dijkstra(start - 1, -1, vis, dst, graph.GetAdjList()); | ||||||||||
|
||||||||||
return dst; | ||||||||||
} | ||||||||||
|
||||||||||
void Dijkstra(int v, int from, vector<int>& vis, vector<int>& dst, | ||||||||||
EchoPr marked this conversation as resolved.
Show resolved
Hide resolved
EchoPr marked this conversation as resolved.
Show resolved
Hide resolved
EchoPr marked this conversation as resolved.
Show resolved
Hide resolved
EchoPr marked this conversation as resolved.
Show resolved
Hide resolved
EchoPr marked this conversation as resolved.
Show resolved
Hide resolved
EchoPr marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: parameter 'from' is unused [misc-unused-parameters]
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: parameter 'vis' is unused [misc-unused-parameters]
Suggested change
|
||||||||||
const AdjacencyList adj) { | ||||||||||
EchoPr marked this conversation as resolved.
Show resolved
Hide resolved
EchoPr marked this conversation as resolved.
Show resolved
Hide resolved
EchoPr marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: the const qualified parameter 'adj' is copied for each invocation; consider making it a reference [performance-unnecessary-value-param] lib/src/util.hpp:9: - const AdjacencyList);
+ const AdjacencyList&);
Suggested change
|
||||||||||
using Pair = pair<int, int>; | ||||||||||
|
||||||||||
priority_queue<Pair, vector<Pair>, greater<Pair>> q; | ||||||||||
|
||||||||||
q.push({0, v}); | ||||||||||
while (!q.empty()) { | ||||||||||
auto [cur_d, v] = q.top(); | ||||||||||
q.pop(); | ||||||||||
|
||||||||||
if (cur_d > dst[v]) continue; | ||||||||||
|
||||||||||
for (auto [u, w] : adj[v]) { | ||||||||||
if (dst[u] > dst[v] + w) { | ||||||||||
dst[u] = dst[v] + w; | ||||||||||
|
||||||||||
q.push({dst[u], u}); | ||||||||||
} | ||||||||||
} | ||||||||||
} | ||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#pragma once | ||
|
||
#include <vector> | ||
|
||
#include "graph.hpp" | ||
|
||
std::vector<int> FindWays(algo::Graph, int); | ||
|
||
void Dijkstra(int, int, std::vector<int>&, std::vector<int>&, | ||
const AdjacencyList); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,25 @@ | ||
int main() { return 0; } | ||
#include <iostream> | ||
|
||
#include "graph.hpp" | ||
|
||
EchoPr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
int main() { | ||
int vertexes_num, edges_num; | ||
std::cin >> vertexes_num >> edges_num; | ||
|
||
algo::Graph graph(vertexes_num, edges_num); | ||
|
||
for (int i = 0; i < edges_num; i++) { | ||
int a, b, w; | ||
|
||
std::cin >> a >> b >> w; | ||
|
||
graph.AddEdge(a, b, w); | ||
} | ||
|
||
std::cout << "Topsort:" << std::endl; | ||
for (auto i : graph.TopologicalSort(0)) { | ||
std::cout << i + 1 << " "; | ||
} | ||
|
||
std::cout << std::endl; | ||
} |
Uh oh!
There was an error while loading. Please reload this page.