Submission #1270881

#TimeUsernameProblemLanguageResultExecution timeMemory
1270881andrezitosRace (IOI11_race)C++20
0 / 100
0 ms328 KiB
#include "race.h"
#include <bits/stdc++.h>
using namespace std;

#define ll long long int
#define INF 100000000000000LL

int flagAtual=1;

vector<pair<int, ll>> melhor;
vector<bool> block;
vector<pair<int, ll>> edges_dist;

// Respota.
ll menor_K = INF;

//calcula o tamanho da subarvore
void get_SubTreeSize( vector<vector<pair<int, int>>>  &adj, vector<int> &subtreeSz, int v, int pai) {
  subtreeSz[v] = 1;
  for(auto& [u, val] : adj[v]) {
    if(u == pai || block[u]) continue;
    get_SubTreeSize(adj,subtreeSz,u,v);
    subtreeSz[v] += subtreeSz[u];
  }
}

//percorre todos os vertices  e retorna o centroide...
int findCentroid(vector<vector<pair<int, int>>>  &adj, vector<int> &subtreeSz, int v, int pai, int size) {
  bool isCentroid = true;

  int maiorVerts=-1;
  int next=-1;
  for (int i=0; i<adj[v].size(); i++) if (adj[v][i].first != pai && !block[adj[v][i].first]) {
      if (subtreeSz[adj[v][i].first] > maiorVerts) {maiorVerts = subtreeSz[adj[v][i].first]; next = adj[v][i].first; }
      if (subtreeSz[adj[v][i].first] > size / 2) 
        isCentroid = false;
  }
  
  if (!isCentroid) {
      subtreeSz[v] = size - subtreeSz[v] + 1;
      return findCentroid(adj, subtreeSz, next, v, size);
  } 

  return v;
}


void dfs1(vector<vector<pair<int, int>>>&adj, int v, int pai, int dist, int total, int K) {
  if(dist > K) return;
  edges_dist[v] = {total, dist};

  ll aux = melhor[K-dist].second == flagAtual? melhor[K-dist].first : INF;

  if(aux + total < menor_K)
    menor_K = aux + total;

  for(auto& [ch, val] : adj[v])
    if(ch != pai && !block[ch])
      dfs1(adj, ch, v, dist + val, total+1, K);
}

void dfs2(vector<vector<pair<int, int>>>&adj, int v, int pai, int K) {
  int edges = edges_dist[v].first;
  ll  dist = edges_dist[v].second;
  if(dist > K) return;

  if(melhor[dist].second != flagAtual || melhor[dist].first > edges) {
    melhor[dist].first = edges;
    melhor[dist].second = flagAtual;
  }

	for (auto& [ch, val] : adj[v]) 
    if(!block[ch] && ch != pai) 
      dfs2(adj, ch, v, K);
}

int best_path(int N, int K, int H[][2], int L[]) {
  vector<vector<pair<int, int>>> adj(N); 
  vector<int> subtreeSz(N);    

  melhor.assign(K+1, {INF, 0});
  block.assign(N, false);
  edges_dist.assign(N, {0, 0});
  
  menor_K = INF;
  flagAtual = 1;

  for(int i = 0; i < N-1; i++) {
    adj[H[i][0]].push_back({H[i][1], L[i]});
    adj[H[i][1]].push_back({H[i][0], L[i]});
  }

  queue<int> Q; 
  Q.push(0);
  while(!Q.empty()) {
    int node = Q.front();
    Q.pop(); 
    
    get_SubTreeSize(adj, subtreeSz, node, -1);
    int cent = findCentroid(adj, subtreeSz, node, -1, subtreeSz[node]);
    block[cent] = true;
    
    melhor[0] = {0, flagAtual};
    for(auto& [ch, val] : adj[cent]) {
      if(!block[ch]) {
        dfs1(adj, ch, cent, val, 1, K);
        dfs2(adj, ch, cent, K);
        Q.push(ch);
      }
    }
    flagAtual++;
  }

  if(menor_K == INF) menor_K = -1;
  return menor_K;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...