Cod sursa(job #1111922)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 19 februarie 2014 11:36:04
Problema Componente tare conexe Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.96 kb
#include <fstream>
#include <vector>
#include <algorithm>

using namespace std;

class Graph {
  public:
    static const int NIL = -1;

    Graph(const int _v = 0):
      v(_v),
      edges(vector< vector<int> >(_v, vector<int>())) {}

    int V() const {
        return v;
    }

    vector<int>::const_iterator EdgesBegin(const int x) const {
        return edges[x].begin();
    }

    vector<int>::const_iterator EdgesEnd(const int x) const {
        return edges[x].end();
    }

    void AddEdge(const int from, const int to) {
        edges[from].push_back(to);
    }

    vector< vector<int> > GetStronglyConnectedComponents() const {
        Graph transposedGraph = Graph(v);
        for (int x = 0; x < v; ++x)
            for (vector<int>::const_iterator y = edges[x].begin(); y != edges[x].end(); ++y)
                transposedGraph.AddEdge(*y, x);
        vector<int> sign = vector<int>(v, 0), topologicalOrder;
        vector< vector<int> > components;
        for (int x = 0; x < v; ++x)
            if (sign[x] == 0)
                DFP(x, sign, topologicalOrder);
        reverse(topologicalOrder.begin(), topologicalOrder.end());
        for (vector<int>::const_iterator x = topologicalOrder.begin(); x != topologicalOrder.end(); ++x) {
            if (sign[*x] == 1) {
                vector<int> currentComponent;
                transposedGraph.DFM(*x, sign, currentComponent);
                components.push_back(currentComponent);
            }
        }
        return components;
    }

  private:
    int v;
    vector< vector<int> > edges;

    void DFP(const int x, vector<int> &sign, vector<int> &topologicalOrder) const {
        ++sign[x];
        for (vector<int>::const_iterator y = edges[x].begin(); y != edges[x].end(); ++y)
            if (sign[*y] == 0)
                DFP(*y, sign, topologicalOrder);
        topologicalOrder.push_back(x);
    }

    void DFM(const int x, vector<int> &sign, vector<int> &component) const {
        --sign[x];
        component.push_back(x);
        for (vector<int>::const_iterator y = edges[x].begin(); y != edges[x].end(); ++y)
            if (sign[*y] == 1)
                DFM(*y, sign, component);
    }
};

Graph G;
vector< vector<int> > Components;

void Solve() {
    Components = G.GetStronglyConnectedComponents();
}

void Read() {
    ifstream cin("ctc.in");
    int v, e;
    cin >> v >> e;
    G = Graph(v);
    for (; e > 0; --e) {
        int from, to;
        cin >> from >> to;
        G.AddEdge(--from, --to);
    }
    cin.close();
}

void Print() {
    ofstream cout("ctc.out");
    cout << int(Components.size()) << "\n";
    for (int i = 0; i < int(Components.size()); ++i) {
        for (vector<int>::const_iterator x = Components[i].begin(); x != Components[i].end(); ++x)
            cout << *x + 1 << " ";
        cout << "\n";
    }
    cout.close();
}

int main() {
    Read();
    Solve();
    Print();
    return 0;
}