Cod sursa(job #1756350)

Utilizator dtoniucDaniel Toniuc dtoniuc Data 12 septembrie 2016 17:55:05
Problema Componente tare conexe Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.33 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, vector<Node*> &vector);
vector<vector<Node*>*>* GetStrongConnectedComponents(int n, Node** graph, vector<Node*> &list);
Node** ReverseGraph(int n, Node** graph);
vector<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);

    vector<Node*> *list = ComputeTopologicalOrder(n, graph);
    vector<Node*> list2;

    graph = ReverseGraph(n, graph);

    for(int i = 0; i < n; i++)
	{
    	list2.push_back(graph[(*list)[i]->val]);
	}
    delete list;

    vector<vector<Node*>*> *result = GetStrongConnectedComponents(n, graph, list2);

    fout << result->size() << "\n";
    for(int i = 0; i < result->size(); i++)
    {
    	for(int j = 0; j < (*result)[i]->size(); j++)
    	{
    		fout << (*((*result)[i]))[j]->val << " ";
    	}
    	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;
}

vector<Node*>* ComputeTopologicalOrder(int n, Node** graph)
{
	vector<Node*> *list = new vector<Node*>();

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

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

	return list;
}

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

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

		currentEdge = currentEdge->next;
	}

	marked[currentNode->val] = 2;
	list.push_back(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;
}

vector<vector<Node*>*>* GetStrongConnectedComponents(int n, Node** graph, vector<Node*> &list)
{
	vector<vector<Node*>*> *result = new vector<vector<Node*>*>();

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

	for(int i = n - 1; i >= 0; i--)
	{
		Node* x = list[i];

		if(!marked[x->val])
		{
			vector<Node*> *component = new vector<Node*>();
			ApplyDfs(x, marked, *component);
			result->push_back(component);
		}
	}

	return result;
}