Submission #618019

#TimeUsernameProblemLanguageResultExecution timeMemory
618019RichemSplit the Attractions (IOI19_split)C++14
100 / 100
149 ms24260 KiB
#include "split.h" #include <iostream> #include <vector> using namespace std; const int MAX_SOMMET = 1e5+42; vector<int> adj[MAX_SOMMET]; int iEnsemble[3] = {1, 2, 3}; int tEnsemble[3]; int nbSommet, nbArete; vector<int> arbre[MAX_SOMMET]; bool vu[MAX_SOMMET] = {0}; void calcArbre(int sommet) { vu[sommet] = 1; for(auto voisin : adj[sommet]) { if(!vu[voisin]) { arbre[sommet].push_back(voisin); arbre[voisin].push_back(sommet); calcArbre(voisin); } } } int tailleComp[MAX_SOMMET] = {0}; int calcTaille(int sommet, int pere) { tailleComp[sommet] = 1; for(auto voisin : arbre[sommet]) { if(voisin == pere) continue; tailleComp[sommet] += calcTaille(voisin, sommet); } return tailleComp[sommet]; } int calcCentroid(int sommet, int pere) { for(auto voisin : arbre[sommet]) { if(voisin == pere) continue; if(tailleComp[voisin] * 2 > nbSommet) return calcCentroid(voisin, sommet); } return sommet; } int centroid; int uf[MAX_SOMMET]; int tailleUf[MAX_SOMMET]; int trouver(int x) { if(uf[x] == x) return x; return uf[x] = trouver(uf[x]); } void unir(int a, int b) { int pa = trouver(a); int pb = trouver(b); if(pa != pb) { uf[pb] = pa; tailleUf[pa] += tailleUf[pb]; } } void initUf(int sommet, int pere) { if(pere != centroid && sommet != centroid) unir(pere, sommet); for(auto voisin : arbre[sommet]) { if(voisin == pere) continue; initUf(voisin, sommet); } } int idComp() { for(int sommet = 0; sommet < nbSommet; sommet++) { if(tailleUf[trouver(sommet)] >= tEnsemble[0] && sommet != centroid) return trouver(sommet); } for(int sommet = 0; sommet < nbSommet; sommet++) { for(auto voisin : adj[sommet]) { if(sommet == centroid || voisin == centroid) continue; unir(sommet, voisin); if(tailleUf[trouver(sommet)] >= tEnsemble[0]) return trouver(sommet); } } return -1; } int compA; vector<int> rep; bool vuA[MAX_SOMMET] = {0}; int nbRestantA; void dfsA(int sommet) { if(vuA[sommet] || trouver(sommet) != compA || nbRestantA == 0) return; vuA[sommet] = 1; rep[sommet] = iEnsemble[0]; nbRestantA--; for(auto voisin : adj[sommet]) dfsA(voisin); } bool vuB[MAX_SOMMET] = {0}; int nbRestantB; void dfsB(int sommet) { if(vuB[sommet] || nbRestantB == 0 || rep[sommet] != 0) return; vuB[sommet] = 1; nbRestantB--; rep[sommet] = iEnsemble[1]; for(auto voisin : adj[sommet]) dfsB(voisin); } vector<int> find_split(int n, int a, int b, int c, vector<int> p, vector<int> q) { nbSommet = n, nbArete = p.size(); tEnsemble[0] = a, tEnsemble[1] = b, tEnsemble[2] = c; for(int sommet = 0; sommet < nbSommet; sommet++) { tailleUf[sommet] = 1; uf[sommet] = sommet; rep.push_back(0); } for(int id : {0, 1, 0}) { if(tEnsemble[id] > tEnsemble[id+1]) { swap(tEnsemble[id], tEnsemble[id+1]); swap(iEnsemble[id], iEnsemble[id+1]); } } for(int id = 0; id < nbArete; id++) { adj[p[id]].push_back(q[id]); adj[q[id]].push_back(p[id]); } calcArbre(0); calcTaille(0, -1); centroid = calcCentroid(0, -1); initUf(centroid, -1); compA = idComp(); if(compA == -1) return rep; nbRestantA = tEnsemble[0]; for(auto voisin : adj[centroid]) { if(trouver(voisin) == compA) { dfsA(voisin); break; } } nbRestantB = tEnsemble[1]; dfsB(centroid); for(int sommet = 0; sommet < nbSommet; sommet++) { if(rep[sommet] == 0) rep[sommet] = iEnsemble[2]; } return rep; }
#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...