#include <list>
#include <stack>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class Graph
{
int N; // nr varfuri
int M; //nr muchii
// listele de adiacenta
list<int>* adj;
// folosita de sortare topologica pt rezultat
void topological_sort_bfs(int v, bool visited[], stack<int>& Stack);
public:
Graph(string file_name);
void topological_sort();
};
Graph::Graph(string file_name)
{
ifstream graph_file;
graph_file.open(file_name);
graph_file >> N >> M;
//cout << N << M << endl;
adj = new list<int>[N];
int v, w;
while (graph_file >> v >> w)
{
adj[v].push_back(w);
//cout << v << w << endl;
}
}
// functia recursiva folosita de topological sort
void Graph::topological_sort_bfs(int v, bool visited[], stack<int>& Stack)
{
// varful curent il marcam ca vizitat
visited[v] = true;
// recurenta pt toate varfurile adiacente varfului curent v
list<int>::iterator it;
for (it = adj[v].begin(); it != adj[v].end(); ++it)
if (!visited[*it])
{
//cout << "test"<<*it<<endl;
topological_sort_bfs(*it, visited, Stack);
}
//stack salveaza rezultatul
Stack.push(v);
//cout << v<<endl;
}
void Graph::topological_sort()
{
stack<int> Stack;
// toate varfurile sunt nevizitate
bool* visited = new bool[N];
for (int i = 0; i < N; i++)
visited[i] = false;
// pt fiecare varf apelam functia recursiva
for (int i = 0; i < N; i++)
if (visited[i] == false)
{
//cout << i << endl;
topological_sort_bfs(i, visited, Stack);
}
ofstream out_file;
out_file.open("sortaret.out");
while (Stack.empty() == false)
{
out_file << Stack.top() << " ";
Stack.pop();
}
}
int main()
{
Graph g("sortaret.in");
g.topological_sort();
return 0;
}