Cod sursa(job #1756329)

Utilizator dtoniucDaniel Toniuc dtoniuc Data 12 septembrie 2016 17:16:26
Problema Componente tare conexe Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 3.4 kb
#include <fstream>
#include <deque>
#include <queue>
#include <vector>

using namespace std;

typedef struct node
{
	int val;
	struct edge *neighbourListHead;
public:
	node(int val) { this->val = val; neighbourListHead = NULL; };
}Node;

typedef struct edge
{
	struct node *end;
	struct edge *next;
public:
	edge(struct node* end) { this->end = end; next = NULL; };
}Edge;

void ApplyDfs(Node* currentNode, int* marked, deque<Node*> &queue);
deque<Node*>* GetStrongConnectedComponents(int n, Node** graph, deque<Node*> &topologicalListm, int &k);
Node** ReverseGraph(int n, Node** graph);
deque<Node*>* ComputeTopologicalOrder(int n, Node** graph);
Node** CreateGraph(int n, int m, istream &fin);

int main()
{
    ifstream fin;
    ofstream fout;
    fout.open("ctc.out");
    fin.open("ctc.in");

    int n, m, k;
    fin >> n >> m;
    Node** graph = CreateGraph(n, m, fin);

    deque<Node*>* topologicalList = ComputeTopologicalOrder(n, graph);
    deque<Node*> topologicalList2;

    graph = ReverseGraph(n, graph);
    while(!topologicalList->empty())
	{
    	topologicalList2.push_front(graph[topologicalList->back()->val]);
    	topologicalList->pop_back();
	}
    delete topologicalList;

    deque<Node*>* listOfQueues = GetStrongConnectedComponents(m, graph, topologicalList2, k);

    fout << k << "\n";
    for(int i = 1; i <= k; i++)
    {
    	while(!listOfQueues[i].empty())
		{
			fout << listOfQueues[i].front()->val << " ";
			listOfQueues[i].pop_front();
		}
    	fout << "\n";
    }
    fin.close();
    fout.close();
    return 0;
}

Node** CreateGraph(int n, int m, istream &fin)
{
	Node** graph = new Node*[n + 1]();

	for(int i = 1; i <= n; i++)
		graph[i] = new Node(i);

	int x, y;
	for (int i = 1; i <= m; i++)
	{
		fin >> x >> y;

		Edge* edge = new Edge(graph[y]);
		edge->next = graph[x]->neighbourListHead;
		graph[x]->neighbourListHead = edge;
	}

	return graph;
}

deque<Node*>* ComputeTopologicalOrder(int n, Node** graph)
{
	deque<Node*> *queue = new deque<Node*>();

	int *marked = new int[n + 1]();

	for(int i = 1; i <= n; i++)
	{
		if(!marked[i])
		{
			ApplyDfs(graph[i], marked, *queue);
		}
	}

	return queue;
}

void ApplyDfs(Node* currentNode, int* marked, deque<Node*> &queue)
{
	marked[currentNode->val] = 1;
	Edge* currentEdge = currentNode->neighbourListHead;

	while(currentEdge)
	{
		if(!marked[currentEdge->end->val])
		{
			ApplyDfs(currentEdge->end, marked, queue);
		}

		currentEdge = currentEdge->next;
	}

	marked[currentNode->val] = 2;
	queue.push_front(currentNode);
}

Node** ReverseGraph(int n, Node** graph)
{
	Node** newGraph = new Node*[n + 1]();

	for(int i = 1; i <= n; i++)
		newGraph[i] = new Node(i);

	for(int i = 1; i <= n; i++)
	{
		Edge* currentEdge = graph[i]->neighbourListHead;

		while(currentEdge)
		{
			Edge* newEdge = new Edge(newGraph[i]);
			newEdge->next = newGraph[currentEdge->end->val]->neighbourListHead;
			newGraph[currentEdge->end->val]->neighbourListHead = newEdge;

			Edge* tmp = currentEdge;
			currentEdge = currentEdge->next;
			delete tmp;
		}
	}

	delete graph;
	return newGraph;
}

deque<Node*>* GetStrongConnectedComponents(int n, Node** graph, deque<Node*> &topologicalList, int &k)
{
	deque<Node*> *queueList = new deque<Node*>[n + 1]();
	k = 0;

	int *marked = new int[n + 1]();

	while(!topologicalList.empty())
	{
		Node* x = topologicalList.front();
		topologicalList.pop_front();

		if(!marked[x->val])
		{
			ApplyDfs(x, marked, queueList[++k]);
		}
	}

	return queueList;
}