Logo Wy Online Judge

WyOJ

Paste!

#include <algorithm> 
#include <iostream>
#include <numeric>
#include <vector>

struct Graph{
    unsigned n;
    std::vector<std::vector<unsigned>> table;
    void add_edge(unsigned from, unsigned to) {
        table[from].push_back(to);
    }
    auto& operator[] (unsigned pos) const {
        return table[pos];
    }
    Graph(unsigned size)
        :n(size), table(size)
    {}
}; 

class Tarjan{
    std::vector<unsigned> stack;
    bool* in_stack;
    unsigned it;
    void dfs(unsigned node) {
        dfn[node] = low[node] = it++;
        stack.push_back(node);
        in_stack[node] = true;
        for(auto to : G[node])
            if(dfn[to] == None)
            {
                dfs(to);
                low[node] = std::min(low[node], low[to]);
            }
            else if(in_stack[to])
                low[node] = std::min(low[node], dfn[to]);
        if(low[node] == dfn[node])
        {
            scc.emplace_back();
            while(in_stack[node])
            {
                scc.back().push_back(stack.back());
                in_stack[stack.back()] = false;
                stack.pop_back();
            }
        }
    }    
public:
    enum { None = 1073741824 }; 
    const Graph& G;
    std::vector<unsigned> dfn, low;
    std::vector<std::vector<unsigned>> scc; 
    void operator() () {
        it = 0;
        std::fill(dfn.begin(), dfn.end(), None); 
        scc.clear();
        for(int i = 0; i < G.n; i++)
            if(dfn[i] == None)
                dfs(i);
    }
    Tarjan(const Graph& graph)
        :in_stack(new bool[graph.n]()), G(graph),
        dfn(graph.n), low(graph.n)
    {}
    ~Tarjan() { delete[] in_stack; }
};


int main() {
    using namespace std;
    int n, m;
    cin >> n >> m;
    auto visit = new bool[n];
    auto search = [&] (unsigned node, auto& graph, auto&& self) -> int {
        visit[node] = true;
        int res = 1;
        for(auto to : graph[node])
            if(!visit[to])
                res += self(to, graph, self);
        return res;
    };
    Graph G(n), revG(n);
    Tarjan tarjan(G);
    for(int i = 0; i < m; i++)
    {
        string rltn;
        cin >> rltn;
        G.add_edge(rltn.front() - 'A', rltn.back() - 'A');
        revG.add_edge(rltn.back() - 'A', rltn.front() - 'A');
        tarjan();
        if(tarjan.scc.size() != n)
        {
            cout << "Inconsistency found after " << i + 1 << " relations." << endl;
            goto END;
        }
        auto front = new int[n];
        bool exist = true;
        for(int i = 0; i < n; i++)
        {
            fill_n(visit, n, false);
            front[i] = search(i, revG, search);
            exist &= front[i] + search(i, G, search) == n + 1;
        }
        if(exist)
        {
            cout << "Sorted sequence determined after " << i + 1 << " relations: ";
            auto seq = new char[n];
            iota(seq, seq + n, 'A');
            sort(seq, seq + n, [&] (char x, char y) {
                return front[x - 'A'] < front[y - 'A'];
            });
            for(int i = 0; i < n; i++)
                cout << seq[i];
            cout << ".\n"; 
            delete[] seq;
            goto END;
        }
        delete[] front;
    }
    cout << "Sorted sequence cannot be determined." << endl;
END: 
    delete[] visit;
    return 0;
}