Cod sursa(job #2816272)

Utilizator Stefan_BircaBirca Stefan Stefan_Birca Data 11 decembrie 2021 11:14:42
Problema Paduri de multimi disjuncte Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.92 kb
#include <bits/stdc++.h>
using namespace std;

/**
Componente tare conexe (Strong connected)

Un digraf este tare conex daca exista drum intre oricare
doua noduri.
*/
vector<int> h[100003]; /// liste ad.
vector<int> g[100003]; /// liste ad. pe arce inverse
vector<int> L[100005]; /// lista ad al grafului
int n, m, nrc;
int st[100003], top;
int viz[100003];
int X[100005], Y[100005], c[100005];
///c[i] = nr comp conexe care

void Citire()
{
    int i, j;
    cin >> n >> m;
    for (int k = 1; k <= m; k++)
    {
        cin >> i >> j;
        X[k] = i;
        Y[k] = j;
        h[i].push_back(j);
        g[j].push_back(i);
    }
    for (i = 1; i <= n; i++)
    {
        sort(h[i].begin(), h[i].end());
        sort(g[i].begin(), g[i].end());
    }
}

void DFSF(int k)
{
    viz[k] = 1;
    for (int i : h[k])
        if (viz[i] == 0) DFSF(i);
    st[++top] = k;
}

/// Acum viz[i]=1 inseamna nevizitat si
///      viz[i]=0 inseamna vizitat
void DFS(int k)
{
    viz[k] = 0;
    for (int i : g[k])
        if (viz[i] == 1) DFS(i);
    c[k] = nrc;
}

void ConstrCTC()
{
    int i;
    /// sortare topologica
    for (i = 1; i <= n; i++)
        if (viz[i] == 0)
            DFSF(i);
    /// determinare c.t.c
    for (i = n; i >= 1; i--)
        if (viz[st[i]] == 1)
        {
            nrc++;
            DFS(st[i]);
        }
}

void DigrafulCTC()
{
    for (int i = 1; i <= m; i++)
        if (c[X[i]] != c[Y[i]])
            L[c[X[i]]].push_back(c[Y[i]]);
}

void Afisare()
{
    for (int i = 1; i <= nrc; i++)
        sort(L[i].begin(), L[i].end());
    for (int i = 1; i <= nrc; i++)
        if (L[i].size() == 0) cout << "0\n";
        else
        {
            for (int j : L[i])
                cout << j << " ";
            cout << "\n";
        }
}

int main()
{
    Citire();
    ConstrCTC();
    DigrafulCTC();
    Afisare();

    return 0;
}