Pagini recente » Cod sursa (job #1104283) | Cod sursa (job #1804692) | Cod sursa (job #2182612) | Cod sursa (job #24332) | Cod sursa (job #2816272)
#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;
}