Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<iostream>
- #include<vector>
- #include<algorithm>
- enum Color {
- WHITE,
- GRAY,
- BLACK
- };
- class Graph {
- private:
- std::vector < std::vector<size_t>> data;
- public:
- Graph(size_t N);
- ~Graph(){}
- void AddEdge(size_t from, size_t to);
- size_t Addition();
- std::vector<std::vector<size_t>> Strong_Connectivity();
- Graph Inversion() const;
- void DFS(size_t from, std::vector<Color>& Colors, std::vector<std::pair<size_t, size_t>>& time_out, size_t& time);
- void DFS(size_t from, std::vector<Color>& Colors, std::vector<size_t>& component);
- std::vector<std::pair<size_t, size_t>> DFS_Full();
- std::vector<std::vector<size_t>> DFS_Full(std::vector<size_t> order);
- std::vector<size_t> GetVertices(size_t from);
- };
- Graph::Graph(size_t N) {
- for (size_t i = 0; i < N; ++i) {
- std::vector<size_t> tmp;
- this->data.push_back(tmp);
- }
- }
- void Graph::AddEdge(size_t from, size_t to) {
- if (from != to) {
- this->data.at(from).push_back(to);
- }
- }
- std::vector<size_t> Graph::GetVertices(size_t from) {
- return this->data.at(from);
- }
- void Graph::DFS(size_t from, std::vector<Color>& Colors, std::vector<std::pair<size_t, size_t>>& time_out, size_t& time) {
- Colors.at(from) = GRAY;
- std::vector<size_t> to = this->GetVertices(from);
- for (size_t i = 0; i < to.size(); ++i) {
- if (Colors.at(to.at(i)) == WHITE) {
- time++;
- this->DFS(to.at(i), Colors, time_out, time);
- }
- }
- Colors.at(from) = BLACK;
- time_out.at(from).second = ++time;
- }
- std::vector<std::pair<size_t, size_t>> Graph::DFS_Full() {
- std::vector<Color> Colors;
- for (size_t i = 0; i < this->data.size(); ++i) Colors.push_back(WHITE);
- std::vector<std::pair<size_t, size_t>> time_out;
- for (size_t i = 0; i < this->data.size(); ++i) time_out.push_back(std::make_pair(i, 0));
- size_t time = 1;
- for (size_t i = 0; i < this->data.size(); ++i) {
- if (Colors.at(i) != WHITE) continue;
- this->DFS(i, Colors, time_out, time);
- time++;
- }
- return time_out;
- }
- std::vector<std::vector<size_t>> Graph::DFS_Full(std::vector<size_t> order) {
- std::vector<Color> Colors;
- for (size_t i = 0; i < order.size(); ++i) Colors.push_back(WHITE);
- std::vector < std::vector<size_t>> components;
- for (size_t i = 0; i < order.size(); ++i) {
- if (Colors.at(order.at(i)) == WHITE) {
- std::vector<size_t> component;
- this->DFS(order.at(i), Colors, component);
- components.push_back(component);
- }
- }
- return components;
- }
- void Graph::DFS(size_t from, std::vector<Color>& Colors, std::vector<size_t>& component) {
- component.push_back(from);
- Colors.at(from) = GRAY;
- std::vector<size_t> to = this->GetVertices(from);
- for (size_t i = 0; i < to.size(); ++i) {
- if (Colors.at(to.at(i)) == WHITE) {
- DFS(to.at(i), Colors, component);
- }
- }
- Colors.at(from) = BLACK;
- }
- Graph Graph::Inversion() const{
- Graph Inv(this->data.size());
- for (size_t i = 0; i < this->data.size(); ++i) {
- for (size_t j = 0; j < this->data.at(i).size(); ++j) {
- Inv.AddEdge(this->data.at(i).at(j), i);
- }
- }
- return Inv;
- }
- bool comp(std::pair<size_t, size_t> p1, std::pair<size_t, size_t> p2) {
- return p1.second > p2.second;
- }
- std::vector<std::vector<size_t>> Graph::Strong_Connectivity() {
- std::vector<std::pair<size_t, size_t>> time_out = this->Inversion().DFS_Full();
- sort(time_out.begin(), time_out.end(), comp);
- std::vector<size_t> order;
- for (size_t i = 0; i < time_out.size(); ++i) {
- order.push_back(time_out.at(i).first);
- }
- return this->DFS_Full(order);
- }
- void Search_Two_numbers(std::vector<size_t> vec, bool& first, bool& second, std::pair<size_t, size_t> digit) {
- for (size_t i = 0; i < vec.size(); ++i) {
- if (digit.first == vec.at(i)) first = true;
- if (digit.second == vec.at(i)) second = true;
- }
- }
- size_t Graph::Addition() {
- std::vector<std::vector<size_t>> components = this->Strong_Connectivity();
- if (components.size() == 1) return 0;
- std::vector<bool> Enter, Exit;
- for (size_t i = 0; i < components.size(); ++i) {
- Enter.push_back(true);
- Exit.push_back(true);
- }
- for (size_t i = 0; i < this->data.size(); ++i) {
- for (size_t j = 0; j < this->data.at(i).size(); ++j) {
- std::pair<size_t, size_t> Edge{ i, data.at(i).at(j) };
- for (size_t k = 0; k < components.size(); ++k) {
- bool first{ false }, second{ false };
- if (!Exit.at(k) && !Enter.at(k)) continue;
- Search_Two_numbers(components.at(k), first, second, Edge);
- if (first && !second) Exit.at(k) = false;
- if (!first && second) Enter.at(k) = false;
- }
- }
- }
- size_t en{ 0 }, ex{ 0 };
- for (size_t i = 0; i < Enter.size(); ++i) {
- en += Enter.at(i);
- ex += Exit.at(i);
- }
- return (en > ex) ? en : ex;
- }
- int main()
- {
- size_t N_vectices, N_Edges;
- std::cin >> N_vectices >> N_Edges;
- Graph enter(N_vectices);
- for (size_t i = 0; i < N_Edges; ++i) {
- size_t tmp1, tmp2;
- std::cin >> tmp1 >> tmp2;
- enter.AddEdge(tmp1 - 1, tmp2 - 1);
- }
- std::cout << enter.Addition() << std::endl;
- system("pause");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement