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(rltn.front() == rltn.back() || 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;
}