Pagini recente » Cod sursa (job #1244457) | Cod sursa (job #1915999) | Cod sursa (job #2891951) | Cod sursa (job #2682873) | Cod sursa (job #3229905)
#include <iostream>
#include <vector>
#include <list>
#include <stack>
#include <fstream>
#include <algorithm>
#include <queue>
#define INFINITE 1000000
using namespace std;
ifstream fin("sortaret.in");
ofstream fout("sortaret.out");
typedef pair<int, vector<int>> sccPair;
vector<sccPair> sccs;
int timestamp;
class Auxiliary {
public:
vector<int> initilialize_arrays(int number_of_vertices, int value) {
vector<int> array(number_of_vertices + 1);
for (int i = 0; i < number_of_vertices; i++) {
array[i] = value;
}
return array;
}
};
class Graph {
private:
int number_of_vertices;
int number_of_edges;
vector<vector<int>> adjacency_list;
vector<int> parents;
vector<int> discovery_times;
vector<int> lowest_time;
vector<int> internal_grade;
public:
Graph(int number_of_vertices, int number_of_edges, vector<vector<int>> adjacency_list) {
Auxiliary auxiliary;
this -> number_of_vertices = number_of_vertices;
this -> number_of_edges = number_of_edges;
this -> parents = auxiliary.initilialize_arrays(number_of_vertices + 1, -1);
this -> discovery_times = auxiliary.initilialize_arrays(number_of_vertices + 1, INFINITE);
this -> lowest_time = auxiliary.initilialize_arrays(number_of_vertices + 1, INFINITE);
this -> internal_grade = auxiliary.initilialize_arrays(number_of_vertices + 1, 0);
this -> adjacency_list = adjacency_list;
}
void addEdge(int src, int dest) {
adjacency_list[src].push_back(dest);
internal_grade[dest] ++;
}
void createGraph() {
for (int i = 0; i < number_of_edges; i++) {
int x, y;
fin >> x >> y;
addEdge(x, y);
}
}
void dfs(int node, stack<int> &nodes_stack,vector<bool> &stack_member) {
discovery_times[node] = ++timestamp;
lowest_time[node] = discovery_times[node];
nodes_stack.push(node);
stack_member[node] = true;
vector<int> ::iterator it;
for (it = adjacency_list[node].begin(); it != adjacency_list[node].end(); it++) {
int neighbour = *it;
if (parents[neighbour] != -1) {
if (stack_member[neighbour] == true) {
lowest_time[node] = min(lowest_time[node], discovery_times[neighbour]);
}
continue;
}
parents[neighbour] = node;
dfs(neighbour, nodes_stack, stack_member);
lowest_time[node] = min(lowest_time[node], lowest_time[neighbour]);
}
if (lowest_time[node] == discovery_times[node]) {
if (nodes_stack.empty() == false) {
vector<int> scc;
int x = nodes_stack.top();
nodes_stack.pop();
stack_member[x] = false;
scc.push_back(x);
// cout << x << " ";
while (x != node && !nodes_stack.empty()) {
x = nodes_stack.top();
scc.push_back(x);
// cout << x << " ";
stack_member[x] = false;
nodes_stack.pop();
}
sort(scc.begin(), scc.end());
sccs.push_back(make_pair(scc.size(), scc));
}
}
}
void tarjanSCC() {
stack<int> nodes_stack;
vector<bool> stack_member(number_of_vertices + 1);
for (int i = 0; i <= number_of_vertices; i++) {
stack_member[i] = false;
}
for (int i = 1; i <= number_of_vertices; i++) {
if (this->parents[i] == -1) {
parents[i] = i;
dfs(i, nodes_stack, stack_member);
}
}
}
void solveTarjanSCCProblem() {
createGraph();
tarjanSCC();
int minimum_pass = -999999, minimum_index = 0;
int lower_limit = -999999;
int index = 0;
fout << sccs.size() << endl;
for (int i = 0; i < sccs.size(); i++) {
minimum_pass = 999999;
for (int j = 0; j < sccs.size(); j++) {
if (minimum_pass >= sccs[j].second[0] && sccs[j].second[0] > lower_limit) {
minimum_pass = sccs[j].second[0];
minimum_index = j;
}
}
if (sccs[minimum_index].first > 0) {
fout << sccs[minimum_index].first << " ";
for (int j = 0; j < sccs[minimum_index].second.size(); j++) {
fout << sccs[minimum_index].second[j] << " ";
}
lower_limit = minimum_pass;
fout << endl;
}
}
}
void solveTarjanCVProblem() {
}
void topoSortDFS(int node, stack<int> &topoStack) {
vector<int> ::iterator it;
for (it = adjacency_list[node].begin(); it != adjacency_list[node].end(); it++) {
int neigh = *it;
if (parents[neigh] == -1) {
parents[neigh] = node;
topoSortDFS(neigh, topoStack);
}
}
topoStack.push(node);
}
void topologicalSortDFS() {
createGraph();
stack <int> topoStack;
for (int i = 1; i <= number_of_vertices; i++) {
if (parents[i] == -1) {
parents[i] = i;
topoSortDFS(i, topoStack);
}
}
while (!topoStack.empty()) {
fout << topoStack.top() << " ";
topoStack.pop();
}
}
void topologicalSortBFS() {
createGraph();
queue<int> topoQueue;
for (int i = 1; i <= number_of_vertices; i++) {
if (!internal_grade[i]) {
topoQueue.push(i);
}
}
while (topoQueue.empty() == 0) {
int current_node = topoQueue.front();
topoQueue.pop();
fout << current_node << " ";
vector<int> ::iterator it;
for (it = adjacency_list[current_node].begin(); it != adjacency_list[current_node].end(); it++) {
int neigh = *it;
internal_grade[neigh]--;
if (internal_grade[neigh] == 0) {
topoQueue.push(neigh);
}
}
}
}
};
int main() {
int number_of_vertices, number_of_edges;
int task = 1;
fin >> number_of_vertices >> number_of_edges;
vector<vector<int>> adjacency_list(number_of_vertices + 1);
Graph graph(number_of_vertices, number_of_edges, adjacency_list);
if (task == 1) {
graph.topologicalSortBFS();
return 0;
}
graph.solveTarjanSCCProblem(); /* rezolva scc-urile folosind algoritmul lui tarjan */
graph.solveTarjanCVProblem();
graph.topologicalSortBFS();
return 0;
}