Cod sursa(job #1905760)

Utilizator vladm98Munteanu Vlad vladm98 Data 6 martie 2017 10:43:03
Problema Componente tare conexe Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 4.92 kb
#include <bits/stdc++.h>

using namespace std;
int sunt_pe_arc[100001];
vector <int> graf[100001];
int n;
int viz[100001];
int nivel_pe_arc[100001];
int sunt_pe_arc2[100001];
int nivel_vechi[100001];
int tata[100001];
int greutate[100001];
int back_conectare[100001];
int conectare[100001];
int cate_conectari;
int caut_stramos[100001];
int stramos (int x)
{
    int king = x, copie;
    while (tata[king]!=king)
        king = tata[king];
    while (x!=tata[x])
    {
        copie = tata[x];
        tata[x] = king;
        x = copie;
    }
    return king;
}
void unire (int x, int y)
{
    int tatax = stramos(x), tatay = stramos(y);
    if (greutate[tatax]>=greutate[tatay])
    {
        sunt_pe_arc[tatay]--;
        sunt_pe_arc[tatax]++;
        tata[tatay] = tatax;
        greutate[tatax]+=greutate[tatay];
    }
    else
    {
        sunt_pe_arc[tatax]--;
        sunt_pe_arc[tatay]++;
        tata[tatax] = tatay;
        greutate[tatay]+=greutate[tatax];
    }
}
void adauga_conectare (int nod, int conect)
{
    if (nod == back_conectare[conect])
        return;
    if (conectare[nod]==0 || (nivel_pe_arc[back_conectare[conectare[nod]]] > nivel_pe_arc[back_conectare[conect]] && nivel_pe_arc[back_conectare[conect]]!=0))
    {
        conectare[nod] = conect;
        nivel_vechi[nod] = back_conectare[conect];
    }
}
stack <int> stiva;
void solve (int a)
{
    stiva.push(a);
    nivel_pe_arc[a] = 1;
    viz[a]=1;
    sunt_pe_arc[a] = 1;
    sunt_pe_arc2[a] = 1;
    while (stiva.empty()==0)
    {
        int nod = stiva.top();
        graf[nod][0]++;
        int i;
        for (i = graf[nod][0]; i<graf[nod].size(); ++i)
        {
            if (viz[graf[nod][i]]==0)
            {
                stiva.push(graf[nod][i]);
                nivel_pe_arc[graf[nod][i]] = nivel_pe_arc[nod]+1;
                viz[graf[nod][i]]=1;
                sunt_pe_arc[stramos(graf[nod][i])]++;
                sunt_pe_arc2[graf[nod][i]]=1;
                break;
            }
            if (stramos(nod)!=stramos(graf[nod][i]) && (sunt_pe_arc[stramos(graf[nod][i])]))
            {
                ++cate_conectari;
                if (sunt_pe_arc2[graf[nod][i]]==1)
                    back_conectare[cate_conectari] = graf[nod][i];
                else
                {
                    back_conectare[cate_conectari] = 0;
                    caut_stramos[cate_conectari] = stramos(graf[nod][i]);
                }
                adauga_conectare(nod, cate_conectari);
            }
        }
        graf[nod][0]=i;
        if (i == graf[nod].size())
        {
            stiva.pop();
            if (stiva.empty()==0 && conectare[nod])
            {
                int nod2 = stiva.top();
                if (stramos(nod)!=stramos(nod2) || nivel_pe_arc[back_conectare[conectare[nod]]]!=0)
                {
                    if (nivel_pe_arc[back_conectare[conectare[nod]]]==0)
                    {
                        if (caut_stramos[conectare[nod]] != stramos(nod2))
                            adauga_conectare(nod2, conectare[nod]);
                        if (stramos(nod)!=stramos(nod2))
                            unire(nod, nod2);
                    }
                    else
                    {
                        adauga_conectare(nod2, conectare[nod]);
                        if (stramos(nod)!=stramos(nod2))
                            unire(nod, nod2);
                    }
                }
            }
            nivel_pe_arc[nod] = 0;
            sunt_pe_arc[stramos(nod)]--;
            sunt_pe_arc2[nod] = 0;
            conectare[nod] = 0;
        }
    }
}
vector <int> afisez[100001];
struct nodes
{
    int nod, boss;
} v[100001];
class cmp
{
public:
    bool operator()(const nodes &a, const nodes &b) const
    {
        if (a.boss != b.boss)
            return a.boss < b.boss;
        return a.nod<b.nod;
    }
};
int unde_bag[100001];
int main()
{
    ifstream fin ("ctc.in");
    ofstream fout ("ctc.out");
    fin >> n;
    int m;
    fin >> m;
    for (int i = 1; i<=n; ++i)
    {
        graf[i].push_back(0);
        tata[i] = i;
        greutate[i] = 1;
    }
    for (int i = 1; i<=m; ++i)
    {
        int x, y;
        fin >> x >> y;
        graf[x].push_back(y);
    }
    //solve(9);
    for (int i = 1; i<=n; ++i)
        if (viz[i]==0)
            solve(i);
    for (int i = 1; i<=n; ++i)
        tata[i] = stramos(i);
    int cate_sunt = 0;
    for (int i = 1; i<=n; ++i)
    {
        if (unde_bag[tata[i]]==0)
        {
            ++cate_sunt;
            unde_bag[tata[i]] = cate_sunt;
        }
        afisez[unde_bag[tata[i]]].push_back(i);
    }
    //sort (v+1, v+n+1, cmp());
    fout << cate_sunt << '\n';
    for (int i = 1; i<=cate_sunt; ++i)
    {
        for (auto x:unde_bag[i])
            fout << x << " ";
        fout << '\n';
    }
    return 0;
}