Cod sursa(job #782647)

Utilizator mihai995mihai995 mihai995 Data 28 august 2012 15:22:22
Problema Santa Scor 0
Compilator cpp Status done
Runda Lista lui wefgef Marime 4.58 kb
#include <fstream>
#include <iostream>
#include <cstring>
#include <stack>
#include <vector>
using namespace std;

const int N = 45005;
const char fail[] = "impossibru\n";

vector<int> graph[N], G[2 * N], comp[N], sol;
int T[2 * N], depth[N], componenta[N], n, S, D, Q, nrComp, nrU;

bool critic[N], use[N], STOP;
stack<int> lista;

struct Muchie{
	int x, y;
	
	Muchie(){
		x = y = 0;
	}
	
	Muchie(int _x, int _y){
		x = _x;
		y = _y;
	}
};

stack<Muchie> St;

ifstream in("santa.in");
ofstream out("santa.out");

void add(Muchie M, int C){
	int x = M.x, y = M.y;
	
	comp[C].push_back(x);
	comp[C].push_back(y);
	
	if (componenta[x] && componenta[x] != C)
		critic[x] = true;
	if (componenta[y] && componenta[y] != C)
		critic[y] = true;
	
	componenta[x] = C;
	componenta[y] = C;
}

void cbc(int x, int D, int T){
	depth[x] = D;
	
	St.push(Muchie(T, x));
	
	for (vector<int> :: iterator it = graph[x].begin() ; it != graph[x].end() ; it++){
		if (*it == T)
			continue;
		
		if (depth[*it]){
			if (!St.empty() && depth[*it] <= depth[St.top().x])
				++nrComp;
			
			while (!St.empty() && depth[*it] <= depth[St.top().x]){
				add(St.top(), nrComp);
				St.pop();
			}
			
			continue;
		}
		
		cbc(*it, 1 + D, x);
	}
		
	if (!St.empty() && St.top().x && St.top().y == x){
		add(St.top(), ++nrComp);
		St.pop();
	}
}

void cleanup(vector<int>& v){
	sort(v.begin(), v.end());
	
	int i, j;
	
	for (i = 0, j = 0 ; i < v.size() ; i++)
		if (v[i] != v[i - 1])
			v[j++] = v[i];
	
	v.resize(j);
}

void read(){
	int m, x, y;
	
	in >> n >> m;
	
	while (m--){
		in >> x >> y;
		
		graph[x].push_back(y);
		graph[y].push_back(x);
	}
	
	in >> S >> D >> Q;
}

void add_edge(int x, int y){
	G[x].push_back(y);
	G[y].push_back(x);
}

void arbore(){
	for (int k = 1 ; k <= nrComp ; k++)
		for (vector<int> :: iterator it = comp[k].begin() ; it != comp[k].end() ; it++)
			if (critic[*it])
				add_edge(N + k, *it);
}

void dfs(int x){
	for (vector<int> :: iterator it = G[x].begin() ; it != G[x].end() ; it++)
		if (!T[*it]){
			T[*it] = x;
			dfs(*it);
		}
}

bool same_comp(int x, int y){
	if (x == y)
		return true;
	
	for (int i = 1 ; i <= nrComp ; i++){
		int nr = 0;
		
		for (vector<int> :: iterator it = comp[i].begin() ; it != comp[i].end() ; it++)
			if (*it == x || *it == y)
				++nr;
		
		if (nr > 1)
			return true;
	}
	
	return false;
}

void sch(int& a, int& b){
	int c = a;
	a = b;
	b = c;
}

void bkt(vector<int>& v, int x, int D){
	if (STOP)
		return;
	
	--nrU;
	sol.push_back(x);
	use[x] = true;
	
	if (x == D){
		STOP = nrU == 0;
		return;
	}
	
	if (D == -1 && !nrU){
		STOP = true;
		return;
	}
	
	
	
	for (vector<int> :: iterator it = graph[x].begin() ; it != graph[x].end() ; it++)
		if (!use[*it]){
			use[*it] = true;
			bkt(v, *it, D);
		}
	
	if (!STOP)
		sol.pop_back();
	
	use[x] = false;
	++nrU;
}

bool solvable(vector<int>& v, int S, int D){
	memset(use, true, sizeof(use));
	
	for (vector<int> :: iterator it = v.begin() ; it != v.end() ; it++)
		use[*it] = false;
	
	STOP = false;
	
	nrU = v.size();
	
	bkt(v, S, D);
	
	return STOP;
}

bool solve(){
	int S, D, C;
	
	while (!lista.empty()){
		S = lista.top(); lista.pop();
		C = lista.top();lista.pop();
		D = -1;
		
		if (!lista.empty())
			D = lista.top();
		
		if (!solvable(comp[C - N], S, D))
			return false;
	}
	
	return true;
}

int main(){
	read();
	
	//componente biconexe
	
	cbc(S, 0, 0);
	
	for (int i = 1 ; i <= nrComp ; i++)
		cleanup(comp[i]);
/*	
	cout << nrComp << "\n";
	
	for (int i = 1 ; i <= nrComp ; i++){
		for (vector<int> :: iterator it = comp[i].begin() ; it != comp[i].end() ; it++)
			cout << *it << " ";
		cout << "\n";
	}
	
	for (int i = 1 ; i <= n ; i++)
		cout << critic[i] << " ";
	
	cout << "\n";
*/	
	arbore(); //construire arbore cbc
	
	//determinare drum
	if (!same_comp(S, Q) && !same_comp(D, Q)){
		out << fail;
		return 0;
	}
	
	if (!same_comp(S, Q))
		sch(S, D);
	
	S = critic[S] ? S : componenta[S] + N;
	D = critic[D] ? D : componenta[D] + N;
	
	T[S] = -1;
	dfs(S);
	
	if (D < N)
		D = T[D];
	
	for (int i = D ; i > 0 ; i = T[i])
		lista.push(i);
	
	if (lista.top() < N)
		lista.pop();
	
	lista.push(Q);
/*	
	while (!lista.empty()){
		cout << lista.top() << " ";
		lista.pop();
	}
*/
	if (!solve()){
		out << fail << "\n";
		return 0;
	}
	
	out << sol.size() << "\n";
	
	for (vector<int> :: iterator it = sol.begin() ; it != sol.end() ; it++)
		out << *it << " ";
		
	out << "\n";

	return 0;
}