Submission #1126866

#TimeUsernameProblemLanguageResultExecution timeMemory
1126866BlancaHMSaveit (IOI10_saveit)C++17
100 / 100
72 ms5808 KiB
#include "grader.h" #include "encoder.h" #include <queue> #include <vector> using namespace std; // Calcula la longitud del camino mas corto desde la fuente al resto de ciudades. vector<int> caminoMasCortoATodasLasCiudades(int fuente, vector<vector<int>> & listaAdyacencia) { int numCiudades = (int) listaAdyacencia.size(); vector<int> distancias(numCiudades, numCiudades + 1); distancias[fuente] = 0; queue<int> colaBfs; colaBfs.push(fuente); while (!colaBfs.empty()) { int ciudad = colaBfs.front(); colaBfs.pop(); for (int & vecina: listaAdyacencia[ciudad]) { if (distancias[vecina] > distancias[ciudad] + 1) { distancias[vecina] = distancias[ciudad] + 1; colaBfs.push(vecina); } } } return distancias; } // Calcula la distancia entre todos los centros de actividades y todas las ciudades. vector<vector<int>> todasLasDistancias( vector<vector<int>> & listaAdyacencia, int numCentros ) { vector<vector<int>> distancias(numCentros); for (int i = 0; i < numCentros; i++) { distancias[i] = caminoMasCortoATodasLasCiudades(i, listaAdyacencia); } return distancias; } // Encuentra el arbol BFS del grafo y saber el padre de cada ciudad. vector<int> definePadres(vector<vector<int>> & listaAdyacencia) { vector<int> padre(listaAdyacencia.size(), -1); queue<int> colaBfs; colaBfs.push(0); padre[0] = -2; while (!colaBfs.empty()) { int ciudad = colaBfs.front(); colaBfs.pop(); // Definimos el padre como la primera conexion que vemos de la ciudad. for (int & vecina: listaAdyacencia[ciudad]) { if (padre[vecina] == -1) { padre[vecina] = ciudad; colaBfs.push(vecina); } } } padre[0] = -1; return padre; } // Codifica un numero decimal en numBits columnas binarias. void codificaEnBits(int numero, int numBits) { vector<int> bits(numBits); for (int idx = numBits - 1; idx >= 0; idx--) { bits[numBits - idx - 1] = numero / (1 << idx); numero %= (1 << idx); } for (int i = 0; i < numBits; i++) { encode_bit((bool) bits[i]); } } void encode(int numCiudades, int numCentros, int numConexiones, int * v1, int * v2) { vector<vector<int>> listaAdyacencia(numCiudades); for (int i = 0; i < numConexiones; i++) { listaAdyacencia[v1[i]].push_back(v2[i]); listaAdyacencia[v2[i]].push_back(v1[i]); } // Primero, definimos y codificamos los padres de todas las ciudades. vector<int> padre = definePadres(listaAdyacencia); for (int i = 1; i < numCiudades; i++) { codificaEnBits(padre[i], 10); } // Encontramos todas las distancias entre centros y ciudades y las codificamos. vector<vector<int>> distancias = todasLasDistancias(listaAdyacencia, numCentros); int ciudad, diferenciaDistancias, diferenciasAgregadas; for (int hub_idx = 0; hub_idx < numCentros; hub_idx++) { ciudad = 1; // Codificamos las distancias en grupos de 3 hasta que ya no haya grupos. while (ciudad + 2 < numCiudades) { // Al tener 3 diferencias, todas ellas en {0, 1, 2}, podemos codificarlas en 5 bits, // ya que 2^5 >= 3^3. diferenciasAgregadas = 0; for (int diff = 0; diff < 3; diff++) { diferenciaDistancias = ( distancias[hub_idx][ciudad + diff] - distancias[hub_idx][padre[ciudad + diff]] + 1 ); diferenciasAgregadas = 3 * diferenciasAgregadas + diferenciaDistancias; } codificaEnBits(diferenciasAgregadas, 5); ciudad += 3; } // Codificamos el resto de forma aislada. while (ciudad < numCiudades) { diferenciaDistancias = distancias[hub_idx][ciudad] - distancias[hub_idx][padre[ciudad]] + 1; // Como la diferencia es 0, 1 o 2, nos bastan 2 bits para codificarla. codificaEnBits(diferenciaDistancias, 2); ciudad++; } } }
#include "grader.h" #include "decoder.h" #include <queue> #include <vector> using namespace std; // Descodifica un numero decimal recibido en numBits columnas binarias. int decode_in_bits(int numBits) { vector <int> bits(numBits); for (int i = 0; i < numBits; i++) { bits[i] = (int) decode_bit(); } int numero = 0; for (int idx = numBits - 1; idx >= 0; idx--) { numero += bits[numBits - idx - 1] * (1 << idx); } return numero; } // Recupera las distancias desde la fuente al resto de ciudades. vector<int> recuperarDistancias( int fuente, vector<vector<int>> & listaAdyacenciaArbol, vector<int> & diferenciasDistancia, vector<int> & padre ) { // Hacemos una BFS desde la fuente, calculando la distancia total con las diferencias. vector <int> distancias(listaAdyacenciaArbol.size(), -1); distancias[fuente] = 0; queue <int> colaBfs; colaBfs.push(fuente); while (!colaBfs.empty()) { int ciudad = colaBfs.front(); colaBfs.pop(); for (int & vecina: listaAdyacenciaArbol[ciudad]) { if (distancias[vecina] != -1) { continue; } if (padre[vecina] == ciudad) { distancias[vecina] = distancias[ciudad] + diferenciasDistancia[vecina]; } else { // Sabemos que padre[ciudad] == vecina en este caso. distancias[vecina] = distancias[ciudad] - diferenciasDistancia[ciudad]; } colaBfs.push(vecina); } } return distancias; } void decode(int numCiudades, int numCentros) { // Primero, reconstruimos el arbol de expansion. vector<vector<int>> listaAdyacenciaArbol(numCiudades); vector<int> padre(numCiudades, -1); for (int i = 1; i < numCiudades; i++) { int p = decode_in_bits(10); listaAdyacenciaArbol[p].push_back(i); listaAdyacenciaArbol[i].push_back(p); padre[i] = p; } // Recuperamos las distancias gracias a las diferencias en el arbol. vector<vector<int>> distancias(numCentros, vector<int>(numCiudades)); vector<int> diferenciasDistancia(numCiudades); for (int centro = 0; centro < numCentros; centro++) { int ciudad = 1, distanciaAgregada; while (ciudad + 2 < numCiudades) { distanciaAgregada = decode_in_bits(5); for (int diff = 2; diff >= 0; diff--) { diferenciasDistancia[ciudad + diff] = (distanciaAgregada % 3) - 1; distanciaAgregada /= 3; } ciudad += 3; } while (ciudad < numCiudades) { diferenciasDistancia[ciudad] = decode_in_bits(2) - 1; ciudad++; } distancias[centro] = recuperarDistancias(centro, listaAdyacenciaArbol, diferenciasDistancia, padre); } // Enviamos las distancias para que el juez las corrija. for (int centro = 0; centro < numCentros; centro++) { for (int ciudad = 0; ciudad < numCiudades; ciudad++) { hops(centro, ciudad, distancias[centro][ciudad]); } } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...