Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include<algorithm>
- #include <vector>
- struct Component
- {
- std::vector<int> component_vertices;
- Component(std::vector<int> arr_of_component_vertices)
- {
- for (int i = 0; i < arr_of_component_vertices.size(); i++)
- {
- component_vertices.push_back(arr_of_component_vertices[i]);
- }
- }
- };
- class Resolver
- {
- int V;
- int E;
- std::vector<std::vector<int>> arr;
- std::vector<std::vector<int>> arr_transp;
- std::vector<Component> arr_of_components;
- std::vector<bool> used;
- std::vector<int> order;
- std::vector<int> components;
- std::vector<std::vector<bool>> table_of_components_graph;
- std::vector<int> component_of_verticle;
- public:
- Resolver(int _V, int _E)
- {
- V = _V;
- E = _E;
- arr.resize(V, std::vector<int>());
- arr_transp.resize(V, std::vector<int>());
- used.resize(V);
- component_of_verticle.resize(V);
- }
- void AddEdgeToGraph(int v, int u)
- {
- arr[v].push_back(u);
- }
- void AddEdgeToTranspGraph(int v, int u)
- {
- arr_transp[v].push_back(u);
- }
- void FirstDFS(int v)
- {
- used[v] = true;
- for (int i = 0; i < arr[v].size(); i++)
- {
- if (!used[arr[v][i]])
- {
- FirstDFS(arr[v][i]);
- }
- }
- order.push_back(v);
- }
- void SecondDFS(int v)
- {
- used[v] = true;
- components.push_back(v);
- for (int i = 0; i < arr_transp[v].size(); i++)
- {
- if (!used[arr_transp[v][i]])
- {
- SecondDFS(arr_transp[v][i]);
- }
- }
- }
- int GetAnswer()
- {
- for (int i = 0; i < V; i++)
- {
- if (!used[i])
- {
- FirstDFS(i);
- }
- }
- for (int i = 0; i < V; i++)
- {
- used[i] = false;
- }
- for (int i = 0; i < V; i++)
- {
- int cur = order[V - i - 1];
- if (!used[cur])
- {
- SecondDFS(cur);
- arr_of_components.push_back(components);
- components.clear();
- }
- }
- if (arr_of_components.size() == 1)
- {
- return 0;
- }
- for (int i = 0; i < arr.size(); i++)
- {
- //находим, какой компоненте связности принадлежит данная вершина
- int cur_comp;
- for (int k = 0; k < arr_of_components.size(); k++)
- {
- if (std::find(arr_of_components[k].component_vertices.begin(), arr_of_components[k].component_vertices.end(), i) != arr_of_components[k].component_vertices.end())
- {
- component_of_verticle[i] = k;
- break;
- }
- }
- }
- table_of_components_graph.resize(arr_of_components.size(), std::vector<bool>(arr_of_components.size()));
- //заполняем таблицу смежности сконденсированного графа
- for (int i = 0; i < arr.size(); i++)
- {
- for (int j = 0; j < arr[i].size(); j++)
- {
- if (component_of_verticle[i] != component_of_verticle[arr[i][j]])
- {
- table_of_components_graph[component_of_verticle[i]][component_of_verticle[arr[i][j]]] = true;
- }
- }
- }
- int X = 0; //out
- int Y = 0; //in
- for (int i = 0; i < table_of_components_graph.size(); i++)
- {
- int cur_out = 0;
- for (int j = 0; j < table_of_components_graph.size(); j++)
- {
- if (table_of_components_graph[i][j] == true)
- {
- cur_out++;
- break;
- }
- }
- if (cur_out == 0)
- {
- X++;
- }
- }
- for (int i = 0; i < table_of_components_graph.size(); i++)
- {
- int cur_in = 0;
- for (int j = 0; j < table_of_components_graph.size(); j++)
- {
- if (table_of_components_graph[j][i] == true)
- {
- cur_in++;
- break;
- }
- }
- if (cur_in == 0)
- {
- Y++;
- }
- }
- return std::max(X, Y);
- }
- };
- int main()
- {
- int V;
- int E;
- std::cin >> V;
- std::cin >> E;
- Resolver resolver(V, E);
- for (int i = 0; i < E; i++)
- {
- int u;
- int v;
- std::cin >> u >> v;
- resolver.AddEdgeToGraph(u - 1, v - 1);
- resolver.AddEdgeToTranspGraph(v - 1, u - 1);
- }
- std::cout << resolver.GetAnswer();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement