답안 #536117

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
536117 2022-03-12T11:53:58 Z Alex_tz307 Parkovi (COCI22_parkovi) C++17
0 / 110
343 ms 36100 KB
#include <bits/stdc++.h>
#define int long long

using namespace std;

const int kN = 2e5;
const int INF = 1e18L;
vector<pair<int, int>> g[1 + kN];
int N, depth[1 + kN], sol[kN];
bitset<1 + kN> mark, covered;

void maxSelf(int &x, int y) {
  if (x < y) {
    x = y;
  }
}

void minSelf(int &x, int y) {
  if (y < x) {
    x = y;
  }
}

int dfs(int u, int par, int radius) {
  if ((int)g[u].size() == 1 && par) {
    return 0;
  }
  int mx = -INF, mn = INF;
  for (auto it : g[u]) {
    int v, w;
    tie(v, w) = it;
    if (v != par) {
      int ret = dfs(v, u, radius);
      if (ret == 0 && covered[v]) { // v este acoperit si nimic din subarborele sau nu ma mai poate ajuta mai mult decat u
        maxSelf(mx, 0);
        minSelf(mn, 0);
        continue;
      }
      if (ret < 0 && ret + w <= 0) { // u este acoperit
        covered[u] = true;
      }
      if (ret < 0 && ret + w > 0) { // v sigur e acoperit si incepand de la u nu se mai acopera nimic nou, deci "resetez"
        ret = 0;
      } else { // creste distanta fata de ultimul nod marcat si mai mult
        ret += w;
      }
      if (ret > radius) { // trebuie sa il marchez pe v acum ca sa acopere alte noduri nemarcate, pentru ca deja u nu poate ajuta
        sol[N++] = v;
        mark[v] = true;
        covered[v] = true;
        ret = min(-radius + w, 0LL); // aproape analog cu cazurile anterioare
        if (w <= radius) {
          covered[u] = true;
        }
      }
      maxSelf(mx, ret);
      minSelf(mn, ret);
    }
  }
  if (mx <= -mn) {
    return mn;
  }
  return mx;
}

bool check(int m, int k) {
  N = 0;
  mark.reset();
  covered.reset();
  if (dfs(1, 0, m) > 0) {
    mark[1] = true;
    sol[N++] = 1;
  } else if (!covered[1]) {
    sol[N++] = 1;
  }
  return N <= k;
}

void testCase() {
  int n, k;
  cin >> n >> k;
  for (int i = 1; i < n; ++i) {
    int u, v, w;
    cin >> u >> v >> w;
    g[u].emplace_back(v, w);
    g[v].emplace_back(u, w);
  }
  int ans = 0, step = (1 << 30);
  while (step) {
    if (!check(ans | step, k)) {
      ans |= step;
    }
    step /= 2;
  }
  ans += 1;
  check(ans, k);
  for (int v = 1; v <= n && N < k; ++v) {
    if (!mark[v]) {
      sol[N++] = v;
    }
  }
  cout << ans << '\n';
  for (int i = 0; i < k; ++i) {
    cout << sol[i] << ' ';
  }
  cout << '\n';
}

int32_t main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  int tests = 1;
  for (int tc = 1; tc <= tests; ++tc) {
    testCase();
  }
  return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 4948 KB Output is correct
2 Incorrect 3 ms 4980 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 302 ms 34412 KB Output is correct
2 Incorrect 289 ms 35552 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 343 ms 36100 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 4948 KB Output is correct
2 Incorrect 3 ms 4980 KB Output isn't correct
3 Halted 0 ms 0 KB -