Cod sursa(job #1901499)

Utilizator vladm98Munteanu Vlad vladm98 Data 3 martie 2017 23:57:50
Problema Componente tare conexe Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 4.27 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 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]])
    {
        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])]))
            {
                unire(graf[nod][i], nod);
                ++cate_conectari;
                if (sunt_pe_arc2[graf[nod][i]]==1)
                    back_conectare[cate_conectari] = graf[nod][i];
                else
                    back_conectare[cate_conectari] = nivel_vechi[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 (stramos(nod)!=stramos(nod2))
                        unire(nod, nod2);
                    adauga_conectare(nod2, conectare[nod]);
                }
            }
            nivel_pe_arc[nod] = 0;
            sunt_pe_arc[stramos(nod)]--;
            sunt_pe_arc2[nod] = 0;
            conectare[nod] = 0;
        }
    }
}
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 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);
    }
    for (int i = 1; i<=n; ++i)
        if (viz[i]==0)
            solve(i);
    for (int i = 1; i<=n; ++i)
    {
        v[i].nod=i;
        v[i].boss = stramos(i);
    }
    sort (v+1, v+n+1, cmp());
    int cate_sunt = 0;
    for (int i = 1; i<=n; ++i)
        if (v[i].boss!=v[i-1].boss)
            cate_sunt++;
    fout << cate_sunt << '\n';
    fout << v[1].nod << " ";
    for (int i = 2; i<=n; ++i)
    {
        if (v[i].boss == v[i-1].boss)
            fout << v[i].nod << " ";
        else fout << '\n' << v[i].nod << " ";
    }
    return 0;
}