Cod sursa(job #2797590)

Utilizator PopelEmilBogdanPopel Emil-Bogdan PopelEmilBogdan Data 10 noiembrie 2021 10:58:44
Problema Sortare topologica Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.68 kb

#include <iostream>
#include <bits/stdc++.h>
using namespace std;

ifstream in("sortaret.in.txt");
ofstream out("sortaret.out.txt");

class Graph
{
private:
    int nodes, edges;
    vector<vector<int>> AdjList;
    vector<vector<int>> AdjListTranspose; ///muchiile in ordine inversa

public:
    Graph(int nodes = 0, int edges = 0)
    {
        this->nodes = nodes;
        this->edges = edges;
    }

    void setNoNodes(int &n){this->edges = n;}
    void setNoEdges(int &n){this->nodes = n;}
    void addEdge(int first, int second){AdjList[first].push_back(second); AdjListTranspose[second].push_back(first);}
    int getNoNodes(){return this->nodes;}
    int getNoEdges(){return this->edges;}
    void readEdges(istream &in);
    void DFS(int, vector<bool> &, vector<int> &, int &);
    void DFStranspose(int, vector<int> &, int &);
    void KOSARAJU();
    void Sortaret();
     void Sortaret_Visit(int, vector<bool>&, stack<int>&);
    ~Graph()
    {
        this->nodes = 0;
        this->edges = 0;
    }
};
    void Graph :: readEdges(istream &in)
    {
        int first, second;
        AdjList.resize(nodes + 1);
        AdjListTranspose.resize(nodes + 1);
        for (int i = 0; i < this->edges; i++)
        {
            in >> first >> second;
            //out<<first<<" "<<second<<" "<<"\n";
            addEdge(first, second);
        }
    }

    void Graph::DFS(int src, vector<bool> &MarcareInOrdine, vector<int>& Stack, int& indx)
    {
    MarcareInOrdine[src] = true; //Il marchez (nodul sursa)
        for(int i = 0; i < AdjList[src].size(); ++i)
        {   //trec prin toti vecinii, iar daca nodul imediat urmator
            //din lista nu a fost vizitat, continui parcurgerea.
            //1-2-6-!7!-5-!4!-!8!- (!5,6!) - !3! - (!2,1!)
            if(!MarcareInOrdine[ AdjList[src][i] ])
                DFS(AdjList[src][i], MarcareInOrdine, Stack, indx);
        }
        //introduc in stiva nodurile la care ajung si nu mai au vecini nevizitati.
        //out<<src<<' ';
        Stack[++indx] = src;
    }   //DE CE STACK.push_back() nu salveaza?

    void Graph::DFStranspose(int src, vector<int>& MarcareOrdineInversa, int& NoCTC)
    {
        MarcareOrdineInversa[src] = NoCTC; //marchez nodul && retin din care componenta conexa face parte
        for(int i = 0; i < AdjListTranspose[src].size(); ++i)
        {
            if( !MarcareOrdineInversa[AdjListTranspose[src][i]] )
                DFStranspose(AdjListTranspose[src][i], MarcareOrdineInversa, NoCTC);
        }
    }

void Graph::KOSARAJU()
{
    int ContorCTC = 1, stackIndex = 0;
    vector<bool> MarcareInOrdine(nodes+1, false);
    vector<int> MarcareInOrdineInversa(nodes+1, 0);
    vector<int> Stack(nodes+2);
    Stack.push_back(0);

    for(int i = 1; i<=nodes; ++i) //pentru fiecare nod
    {
            if( !MarcareInOrdine[i] ) //Daca nu a fost vizitat inca
            DFS(i, MarcareInOrdine, Stack, stackIndex); //DFS marcand toti succesorii sai
    }
    for(int i = nodes; i >= 1; --i)
    {
        if( !MarcareInOrdineInversa[Stack[i]] ) //daca vecinul din lista inversa (transpose) nu a fost vizitat
        {
            DFStranspose(Stack[i], MarcareInOrdineInversa, ContorCTC);
            ContorCTC++;
        }
    }
    out<<ContorCTC-1<<'\n';
/*
    for(int i = 1; i<= ContorCTC; ++i)
        {
            for(int j = 1; j<=MarcareInOrdineInversa.size(); ++i)
            {
                if(MarcareInOrdineInversa[j] == i)
                    out<<j<<' ';
            }
        out<<'\n';
        }
*/
int node_curr, i,j;
for(i = 1; i <= ContorCTC; ++i)
    node_curr =0;
    for(j = 1; j <= MarcareInOrdineInversa.size(); ++j)
    {
        if(i == MarcareInOrdineInversa[j])
            out<<MarcareInOrdineInversa[j]<<' ';
    }
    out<<'\n';
}


void Graph::Sortaret_Visit(int node_curr, vector<bool>& visited, stack<int>& Stack)
{
visited[node_curr] = 1;

//recursiv, apelam pentru toti vecinii
vector<int>::iterator itr;
for(itr = AdjList[node_curr].begin(); itr != AdjList[node_curr].end(); ++itr)
        if(!visited[*itr])
            Sortaret_Visit(*itr, visited, Stack);

Stack.push(node_curr);
}

void Graph::Sortaret()
{
    stack<int> Stack;
    vector<bool> Visited(nodes+2, 0);

  for(int i = 1; i <= nodes; ++i)
        if(!Visited[i])
            Sortaret_Visit(i, Visited, Stack);

  while(!Stack.empty())
  {
      out<<Stack.top()<<' ';
      Stack.pop();
  }

}

int main()
{  ///CTC
    /* int N, M;
    in>>N>>M;
    Graph g(N, M);
    g.readEdges(in);
    g.KOSARAJU();
*/
///sortaret
int N, M;
in>>N, M;
Graph g(N,M);
g.readEdges(in);
g.Sortaret();
    return 0;
}