Submission #1270883

#TimeUsernameProblemLanguageResultExecution timeMemory
1270883andrezitos경주 (Race) (IOI11_race)C++20
0 / 100
1 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<pair<int, ll>> edges_dist;
vector<bool> block;

// Respota.
ll menor_K = INF;

//calcula o tamanho da subarvore
void get_SubTreeSize( vector<vector<pair<int, ll>>>  &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, ll>>>  &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, ll>>>&adj, int v, int pai, ll 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, ll>>>&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, ll>>> 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();

      get_SubTreeSize(adj, subtreeSz, node, -1);
      node= findCentroid(adj, subtreeSz, node, -1, subtreeSz[node]);

      block[node] = true;
      melhor[0] = {0, flagAtual};

      Q.pop();
      for (auto& [ch, val] : adj[node]) 
        if (!block[ch]) {
          dfs1(adj, ch, node, val, 1, K);
          dfs2(adj, ch, node, 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...