Pagini recente » Cod sursa (job #2792171) | Cod sursa (job #109756) | Cod sursa (job #2740823) | Cod sursa (job #794432) | Cod sursa (job #2929084)
/// 4. https://infoarena.ro/problema/ctc
/// Solutia prezenta este bazata pe algoritmul lui Kosaraju, care are rolul de a gasi
/// componentele tare conexe bazandu-ne pe graful transpus al grafului in cauza. Astfel, adaugam pe
/// stiva la o prima parcurgere a grafului initial toate nodurile in ordinea accesarii lor,
/// iar apoi, in functie de cine a fost vizitat primul, mai parcurgem odata in adancime graful transpus, iar fiecare dfs
/// pe care il facem pe acel graf va reprezenta o componenta tare conexa. In principiu, daca facem
/// abstractie de notiunea de "orientat", algoritmul lui kosaraju imi verifica daca un ciclu se regaseste si in
/// graful transpus, lucru ce garanteaza conditia de drum de la nodul x la nodul y, dar si vice-versa.
/// Complexitatea este O(n+m), avand 2 dfs uri
#include <bits/stdc++.h>
using namespace std;
ifstream fin("ctc.in");
ofstream fout("ctc.out");
int n,m,nr;
vector<vector<int>> v, vt, sol;
vector<int> vis;
vector<int> order;
void dfs(int nod)
{
vis[nod] = 1;
for(int i=0; i<v[nod].size(); i++)
{
if(!vis[v[nod][i]])
dfs(v[nod][i]);
}
order.push_back(nod); /// adaugam in stiva fiecare nod
}
void dfst(int nod)
{
vis[nod] = 1;
sol[nr].push_back(nod);
for(int i=0; i<vt[nod].size(); i++)
{
if(!vis[vt[nod][i]])
dfst(vt[nod][i]);
}
}
int main()
{
int a, b;
fin>>n>>m;
v.resize(n+1);
vt.resize(n+1);
for(int i=1; i<=m; i++)
{
fin>>a>>b;
v[a].push_back(b);
vt[b].push_back(a);
}
vis.resize(n+1, 0);
/// dfs pe graful initial
for(int i=1; i<=n; i++)
{
if(!vis[i])
dfs(i);
}
fill(vis.begin(), vis.end(), 0);
reverse(order.begin(), order.end());
for(int i=0; i<order.size(); i++)
{
if(!vis[order[i]])
{
sol.push_back({});
dfst(order[i]);
nr++;
}
}
fout<<nr<<'\n';
for(int i=0; i<nr; i++)
{
for(int j=0;j<sol[i].size();j++)
fout<<sol[i][j]<<' ';
fout<<'\n';
}
return 0;
}