Pagini recente » Cod sursa (job #262544) | Cod sursa (job #1433664) | Cod sursa (job #1734880) | Cod sursa (job #1387831) | Cod sursa (job #1901525)
#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]] && 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();
/*int y = tata[nod];
if (y != stramos(nod))
{
sunt_pe_arc[y]--;
sunt_pe_arc[tata[nod]]++;
}*/
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 (nivel_pe_arc[back_conectare[conectare[nod]]]==0)
{
if (greutate[stramos(nod2)] == 1)
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);
}
}
}
int y = tata[nod];
if (y!=stramos(nod))
{
sunt_pe_arc[y]--;
sunt_pe_arc[stramos(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);
}
//solve(9);
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;
}