Pagini recente » Cod sursa (job #1217812) | Cod sursa (job #1350478) | Cod sursa (job #1655731) | Cod sursa (job #2956684) | Cod sursa (job #2926076)
#include <iostream>
#include <fstream>
#include <vector>
#include <stack>
#include <set>
#include <unordered_map>
//complexitate timp O(n+m)
//complexitate spatiu O(n+m)
using namespace std;
ifstream fin("ctc.in");
ofstream fout("ctc.out");
int n, m;
vector <int> arce[100005]; //<-voi retine graful asa cum este dat de problema
vector <int> redenumiri; //<-fiecare nod va primi un nou numar, care va fi tinut in redenumiri
vector <int> nod_min; //<-se va retine valoarea minima pe care o are un vecin al nodului din aceeasi ctc
vector <bool> pe_stiva; //<-se va marca daca nodul este pe stiva
stack <int> stiva; //<-stiva unde se tin nodurile care ar putea fi in aceeasi ctc cu nodul curent
int id_nou; //<-iterator pentru redenumirea nodurilor
set <int> minime; //<-multime in care tin valorile minime ale nodurilor
unordered_map <int, vector<int>> ctc; //<- tine pentru fiecare valoare minima nodurile care au acea valoare minima
void dfs(int nod)
{
// cout<<"nod: "<<nod<<endl;
redenumiri[nod] = id_nou; //sa da un nou id-nodului
nod_min[nod] = id_nou; //minimul acelui nod este initial chiar el insusi
id_nou++;
stiva.push(nod); //se pune nodul pe stiva
pe_stiva[nod] = true; //se marcheaza nodul ca fiind pe stiva
for (int i = 0; i<arce[nod].size(); i++) //pentru fiecare vecin al nodului curent
{
if(redenumiri[arce[nod][i]]== -1) //daca nodul adiacent nu este vizitat se face dfs pe el
{
dfs(arce[nod][i]);
}
if (pe_stiva[arce[nod][i]]) //daca nodul vecin este pe stiva, val min a nodului curent
{ // devine minimul dintre val min ale celor doua noduri
nod_min[nod] = min(nod_min[nod], nod_min[arce[nod][i]]);
}
}
if (redenumiri[nod] == nod_min[nod]) //daca val_min este egala cu redenumirea, inseamna ca s-a parcurs o ctc
{
while(true)
{
int top = stiva.top(); //se scot toate elementele de pe stiva pana la nodul curent inclusiv
pe_stiva[top] = false; // se marcheaza nodurile scoase de pe stiva
nod_min[top] = redenumiri[nod]; //toate elementele unei ctc trebuie sa aiba acelasi val min
stiva.pop();
if(top == nod)
{
break;
}
}
}
}
int main()
{
fin>>n>>m;
id_nou = 1;
for(int i = 0; i <= n; i++)
{
redenumiri.push_back(-1); //"initializez" vectorii
nod_min.push_back(-1);
pe_stiva.push_back(false);
}
for(int i=0; i<m; i++)
{
int p1, p2; //fac lista de adiacenta
fin>>p1>>p2;
arce[p1].push_back(p2);
}
for(int i=1; i<n+1; i++) //ma asigur ca se face dfs pe toate nodurile
// chiar daca graful are mai multe elemente conexe
{
if(redenumiri[i] == -1)
{
dfs(i);
}
}
for(int i = 1; i < nod_min.size(); i++)
{
//cout<<nod_min[i]<<" ";
minime.insert(nod_min[i]); //fac o multime cu valorile minime ale nodurilor
}
//cout<<endl;
fout<<minime.size();
fout<<endl;
for(auto it = minime.begin(); it != minime.end(); it++)
{
vector<int> vec;
ctc.insert(pair<int, vector<int>>(*it, vec)); //pun empty vectors in map pt val min
}
for(int i = 1; i < nod_min.size(); i++)
{
ctc[nod_min[i]].push_back(i); //inserez nodurile pentru fiecare valoare minima
}
for(auto it = ctc.begin(); it != ctc.end(); it++)
{
for(auto it2 = it->second.begin(); it2 != it->second.end(); it2++)
{
fout<<*it2<<" "; //afisez pt fiecare val min nodurile corespunzatoare, adica ctc-urile
}
fout<<endl;
}
return 0;
}