Submission #1341412

#TimeUsernameProblemLanguageResultExecution timeMemory
1341412simplemind_31Connecting Supertrees (IOI20_supertrees)C++20
0 / 100
1 ms344 KiB
#include "supertrees.h"
#include <bits/stdc++.h>
using namespace std;
struct dsu{
	vector<int> pad,tam;
	int find(int a){return (a==pad[a])?a:pad[a]=find(pad[a]);}
	bool unite(int a,int b){
		if((a=find(a))==(b=find(b)))return false;
		if(tam[a]<tam[b])swap(a,b);
		tam[pad[b]=a]+=tam[b];
		return true;
	}
	dsu(int n){
		pad.resize(n);
		tam.resize(n);
		for(int i=0;i<n;i++)tam[pad[i]=i]=1;
	}
};
int construct(vector<vector<int>> p){
	int n=p.size();
	vector<vector<int>> answer(n,vector<int>(n));
	//vector<bool> esciclo(n);
	// si p=3, entonces no hay solucion porque tenemos que tener 2 ciclos:
	// 0-1,1-3,0-2,2-3,0-3, pero entonces hay 4 caminos e 1 a 2
	dsu clave(n);
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			if(p[i][j]==3)return 0;
			// si es 0 pertenecen a diferentes componentes
			if(p[i][j])clave.unite(i,j);
		}
	}
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			if(!p[i][j] && clave.find(i)==clave.find(j))return 0;
		}
	}
	// no puede haber 2 ciclos en un mismo componente sino habria >=4 caminos de a a b
	// -> cada componente hay a lo mucho un ciclo, y los demas conectan al ciclo
	for(int i=0;i<n;i++){
		vector<int> componentes;
		for(int j=0;j<n;j++)if(clave.find(j)==i)componentes.push_back(j);
		// resolver cada componente
		// si el nodo tiene todo 2,0 y el mismo 1 entonces pertenece al ciclo
		if(componentes.size()<=1)continue;
		/*vector<int> parteciclo;
		for(auto u:componentes){
			int con[3]={0,0,0};
			for(int j=0;j<componentes.size();j++){
				con[p[u][componentes[j]]]++;
			}
			if(con[1]==1){
				parteciclo.push_back(u);
				esciclo[u]=true;
			}
		}
		if(parteciclo.empty()){
			// es un tree;
			for(int j=1;j<componentes.size();j++){
				answer[componentes[j-1]][componentes[j]]=answer[componentes[j]][componentes[j-1]]=1;
			}
			continue;
		}
		//if(parteciclo.size()<=2)return 0;
		// los ciclos se unen
		for(int j=1;j<parteciclo.size();j++){
			answer[parteciclo[j-1]][parteciclo[j]]=answer[parteciclo[j]][parteciclo[j-1]]=1;
		}
		answer[parteciclo[0]][parteciclo.back()]=answer[parteciclo.back()][parteciclo[0]]=1;*/
		// si dos tiene 1 solo camino, entonces estan en el mismo lado
		/*cout << endl << endl;
		for(auto u:componentes){
			cout << u << ' ';
		}
		cout << endl << endl;*/
		dsu subdsu(n);
		for(int j=0;j<componentes.size();j++){
			//if(esciclo[componentes[j]])continue;
			for(int k=j+1;k<componentes.size();k++){
				//if(esciclo[componentes[k]])continue;
				if(p[componentes[j]][componentes[k]]==1){
					if(subdsu.unite(componentes[j],componentes[k])){
						answer[componentes[j]][componentes[k]]=answer[componentes[k]][componentes[j]]=1;
						//cout << componentes[j] << ' ' << componentes[k] << endl << endl;
					}
				}
			}
		}
		// si hay un par que tienen 2 caminos pero pertenecen al mismo lado, entonces es imposible
		for(int j=0;j<componentes.size();j++){
			//if(esciclo[componentes[j]])continue;
			for(int k=j+1;k<componentes.size();k++){
				//if(esciclo[componentes[k]])continue;
				if(p[componentes[j]][componentes[k]]==2 && subdsu.find(componentes[j])==subdsu.find(componentes[k]))return 0;
			}
		}
		// cuantos subcomponentes hay?
		vector<int> subcomponentes;
		for(int j=0;j<componentes.size();j++){
			//if(esciclo[componentes[j]])continue;
			if(subdsu.find(componentes[j])==componentes[j])subcomponentes.push_back(componentes[j]);
		}
		// los jefes de cada subcomponente se conecta
		for(int j=1;j<subcomponentes.size();j++){
			answer[subcomponentes[j-1]][subcomponentes[j]]=answer[subcomponentes[j]][subcomponentes[j-1]]=1;
		}
		answer[subcomponentes[0]][subcomponentes.back()]=answer[subcomponentes.back()][subcomponentes[0]]=1;
		/*if(subcomponentes.size()>parteciclo.size())return 0;
		// cada subcomponente se conecta al ciclo
		for(int j=0;j<subcomponentes.size();j++){
			answer[subcomponentes[j]][parteciclo[j]]=answer[parteciclo[j]][subcomponentes[j]]=1;
		}*/
	}
	build(answer);
	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...