제출 #1342609

#제출 시각아이디문제언어결과실행 시간메모리
1342609Gabriel슈퍼트리 잇기 (IOI20_supertrees)C++20
100 / 100
138 ms30368 KiB
#include "supertrees.h"
#include "bits/stdc++.h"
using namespace std;
bool Final = 0;
int n;
vector<int> Representantes0, Representantes1;
vector< vector<int> > Respuesta, Copia, Grafo, Separaciones, Caminos;
vector< pair<int, int> > Activadores;
bitset<2222> Visitados;
int Buscar0(int a){
	if(Representantes0[a] == a) return a;
	return Representantes0[a] = Buscar0(Representantes0[a]);
}
bool Unir0(int A, int B){
	int a = Buscar0(A), b = Buscar0(B);
	if(Representantes0[a] != Representantes0[b]){
		Representantes0[b] = a;
		return 1;
	}
	return 0;
}
int Buscar1(int a){
	if(Representantes1[a] == a) return a;
	return Representantes1[a] = Buscar1(Representantes1[a]);
}
void Unir1(int A, int B){
	int a = Buscar1(A), b = Buscar1(B);
	Representantes1[b] = a;
}
void DFS(int Nodo, bool S__vuelve, int Activador_0, int Activador_1, int Inicio){
	Visitados[Nodo] = 1;
	S__vuelve = S__vuelve or Nodo == Activador_0 or Nodo == Activador_1;
	//cerr<<Nodo<<" "<<S__vuelve<<" "<<Activador_0<<" "<<Activador_1<<"\n";
	Caminos[Inicio][Nodo] = 1 + S__vuelve;
	for(auto E: Grafo[Nodo]){
		if(!Visitados[E]){
			DFS(E, S__vuelve, Activador_0, Activador_1, Inicio);
		}
	}
}
bool Verificar(){
	Grafo.assign(n, {});
	for(int i = 0; i < n; i++){
		for(int j = 0; j < n; j++){
			if(Respuesta[i][j] == 1){
				//cerr<<i<<" >> "<<j<<"\n";
				Grafo[i].push_back(j);
			}
		}
	}
	bitset<2222> Reinicio;
	/*for(auto E: Separaciones){
		for(auto e: E){
			cerr<<e<<" ";
		}
		cerr<<"\n";
	}*/
	for(int i = 0; i < n; i++){
		//cerr<<i<<"\n";
		DFS(i, 0, Activadores[i].first, Activadores[i].second, i);
		/*cerr<<"\n";
		for(auto E: Caminos[i]) cerr<<E<<" ";
		cerr<<"\n\n";*/
		Visitados = Visitados & Reinicio;
		if(Copia[i] != Caminos[i]){
			//cerr<<"No válido.";
			return 0;
		}
	}
	//cerr<<"Válido.";
	return 1;
}
int construct(vector< vector<int> > p){
	n = p.size();
	Caminos.assign(n, vector<int>(n, 0));
	Separaciones.assign(n, {});
	Copia = p;
	Activadores.assign(n, {-2, -2});
	for(int i = 0; i < n; i++) Representantes0.push_back(i);
	Respuesta.assign(n, vector<int>(n, 0));
	for(int i = 0; i < n; i++){
		for(int j = i + 1; j < n; j++){
			if(p[i][j] == 3) return 0;
			if(p[i][j] != 1) continue;
			if(Unir0(i, j)){
				Respuesta[i][j] = 1;
				Respuesta[j][i] = 1;
			}
			if(Final) return 0;
		}
	}
	set<int> Nuevos;
	for(int i = 0; i < n; i++){
		Nuevos.insert(Buscar0(i));
	}
	map<int, int> Mapeo, iMapeo;
	int m = Nuevos.size();
	auto E = Nuevos.begin();
	for(int i = 0; i < m; i++){
		Representantes1.push_back(i);
		Mapeo[*E] = i;
		iMapeo[i] = *E;
		E++;
	}
	for(int i = 0; i < n; i++){
		for(int j = i + 1; j < n; j++){
			if(p[i][j] != 2) continue;
			Unir1(Mapeo[Representantes0[i]], Mapeo[Representantes0[j]]);
		}
	}
	for(int i = 0; i < m; i++){
		Separaciones[Buscar1(i)].push_back(iMapeo[i]);
	}
	for(auto E: Separaciones){
		if(E.size() <= 1) continue;
		if(E.size() == 2) return 0;
		for(int i = 0; i < int(E.size()); i++){
			int Siguiente = i + 1, Anterior = i - 1;
			if(Siguiente >= int(E.size())) Siguiente = 0;
			if(Anterior < 0) Anterior = int(E.size()) - 1;
			Activadores[E[i]].first = E[Anterior];
			Activadores[E[i]].second = E[Siguiente];
			Respuesta[E[i]][E[Siguiente]] = 1;
			Respuesta[E[Siguiente]][E[i]] = 1;
		}
	}
	for(int i = 0; i < n; i++){
		Activadores[i] = Activadores[Buscar0(i)];
	}
	if(Verificar()) build(Respuesta);
	else return 0;
	return 1;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...