Cod sursa(job #2798616)

Utilizator jaha01Jahaleanu Vlad-Gabriel jaha01 Data 11 noiembrie 2021 17:01:11
Problema Componente tare conexe Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 6.05 kb
#include <iostream>
#include <bits/stdc++.h>

#define MAX_SIZE 10000

using namespace std;

ifstream fbfs("bfs.in");
ofstream gbfs("bfs.out");

ifstream fdfs("dfs.in");
ofstream gdfs("dfs.out");

ifstream fsort("sortaret.in");
ofstream gsort("sortaret.out");

ifstream fctc("ctc.in");
ofstream gctc("ctc.out");


class Graf
{
    int nrNoduri;
    int nrMuchii;
    int start;
    int nr_ctc = 0;
    vector <int> adj[MAX_SIZE];
    vector <int> adjT[MAX_SIZE];
    vector <int> rez[MAX_SIZE];



public:

    void citire_orientat();
    void citire_neorientat();
    void citire_orientat_sortare();
    void citire_ctc();

    void BFS();

    void DFS();
    void DFS_helper(int, vector <bool>&);

    void topological_sort();
    void topological_sort_helper(int, vector <bool>&, stack <int>&);

    void print_ctc();
    void DFS_ctc(int, vector <bool>&, stack <int>&);
    void DFS_transposed(int, vector <bool>&);



};

void Graf::citire_orientat()
{
    int first, second;

    fbfs>>nrNoduri;
    fbfs>>nrMuchii;
    fbfs>>start;

    for(int i = 0; i < nrMuchii; i++)
    {
        fbfs>>first>>second;
        adj[first].push_back(second);
    }
}

void Graf::citire_orientat_sortare()
{
    int first, second;

    fsort>>nrNoduri;
    fsort>>nrMuchii;


    for(int i = 0; i < nrMuchii; i++)
    {
        fsort>>first>>second;
        adj[first].push_back(second);
    }
}

void Graf::citire_neorientat()
{
    int first, second;
    fdfs>>nrNoduri>>nrMuchii;
    for(int i = 0; i < nrMuchii; i++)
    {
        fdfs>>first>>second;
        adj[first].push_back(second);
        adj[second].push_back(first);

    }
}

void Graf::BFS()
{
    queue <int> coada;
    coada.push(start);
    bool visited[MAX_SIZE] = {};
    visited[start] = 1;
    int cost[MAX_SIZE] = {};
    cost[start] = 0;

    int nodCrt;

    while (coada.size())
    {
        nodCrt = coada.front();

        for(int i = 0; i < adj[nodCrt].size(); i++)
        {
            if(!visited[adj[nodCrt][i]])
            {
                coada.push(adj[nodCrt][i]);
                cost[adj[nodCrt][i]] = cost[nodCrt] + 1;
                visited[adj[nodCrt][i]] = 1;
            }
        }
        coada.pop();
    }

    for(int i = 1; i <= nrNoduri; i++)
    {
        if(visited[i] == 1)
            gbfs<<cost[i]<<" ";
        else
            gbfs<<"-1 ";
    }


}

void Graf::DFS()
{
    vector <bool> visited(MAX_SIZE);
    int nrCompConexe = 0;

    for (int i = 1; i <= nrNoduri; i++)
    {
        if(!visited[i])
        {
            DFS_helper(i, visited);
            nrCompConexe += 1;
        }
    }

    gdfs<<nrCompConexe;

}


void Graf::DFS_helper(int s, vector<bool>& visited)
{
    visited[s] = 1;

    for (int i = 0; i < adj[s].size(); i++)
    {
        if(!visited[adj[s][i]])
            DFS_helper(adj[s][i], visited);
    }
}


///sortarea topologica este practic un DFS modificat
///in care daca ajungem intr-un nod care nu mai are vecini nevizitati,
///il trecem intr-o stiva, iar la final afisam stiva

void Graf::topological_sort()
{
    stack <int> stiva;
    vector <bool> visited(MAX_SIZE);

    for (int i = 1; i <= nrNoduri; i++)
    {
        if(!visited[i])
        {
            topological_sort_helper(i, visited, stiva);
        }
    }

    while(!stiva.empty())
    {
        gsort<<stiva.top()<<" ";
        stiva.pop();
    }
}

void Graf::topological_sort_helper(int s, vector<bool>& visited, stack <int>& stiva)
{
    visited[s] = 1;

    for (int i = 0; i < adj[s].size(); i++)
    {
        if(!visited[adj[s][i]])
            topological_sort_helper(adj[s][i], visited, stiva);
    }

    stiva.push(s);
}


///Havel-Hakimi
bool exists(vector <int>& degrees, int n)
{
    while(1)
    {
        sort(degrees.begin(), degrees.end(), greater<int>());

        if(degrees[0] == 0)
            return true;

        int first = degrees[0];

        degrees.erase(degrees.begin());

        if(first > degrees.size())
            return false;

        for(int i = 0; i < first; i++)
        {
            degrees[i]--;
            if (degrees[i] < 0)
                return false;
        }

    }
}


///ctc

void Graf::citire_ctc()
{

    fctc>>nrNoduri>>nrMuchii;

    for(int i = 1; i <= nrMuchii; i++)
    {
        int first, second;
        fctc>>first>>second;
        adj[first].push_back(second);
        adjT[second].push_back(first);
    }
}

void Graf::print_ctc()
{
    stack <int> stiva;
    vector <bool> visited(MAX_SIZE, 0);
    vector <bool> visitedT(MAX_SIZE, 0);

    for (int i = 1; i <= nrNoduri; i++)
    {
        if(visited[i] == 0)
            DFS_ctc(i, visited, stiva);   ///se apeleaza un DFS pe graful normal
    }



    while(!stiva.empty())
    {
        int v = stiva.top();


        if(visitedT[v] == 0)
        {
            DFS_transposed(v, visitedT);
            nr_ctc++;
        }
        stiva.pop();
    }

    gctc<<nr_ctc<<endl;

    for(int i = 0; i < nr_ctc; i++)
    {
        for(auto it: rez[i])
            gctc<<it<<" ";
        gctc<<"\n";
    }

}

void Graf::DFS_ctc(int s, vector <bool>& visited, stack <int>& stiva)
{
    visited[s] = 1;

    for (auto i: adj[s])
    {
        if(!visited[i])
            DFS_ctc(i, visited, stiva);
    }

    stiva.push(s);
}

void Graf::DFS_transposed(int s, vector <bool>& visitedT)
{
    visitedT[s] = 1;

    rez[nr_ctc].push_back(s);

    for (auto i: adjT[s])
    {
        if(!visitedT[i])
            DFS_transposed(i, visitedT);
    }


}

int main()
{
    Graf G;

    //G.citire_orientat();
    //G.BFS();

    //G.citire_neorientat();
    //G.DFS();

    //G.citire_orientat_sortare();
    //G.topological_sort();

    //vector<int> degrees = {3, 2, 1, 0};
    //int n = degrees.size();

    //if(exists(degrees, n) == true) cout<<"yes";
    //else cout<<"no";

    G.citire_ctc();
    G.print_ctc();

    return 0;
}