Submission #1036781

#TimeUsernameProblemLanguageResultExecution timeMemory
1036781juicy수도 (JOI20_capital_city)C++17
100 / 100
1221 ms380100 KiB
#include <bits/stdc++.h>

using namespace std;

#ifdef LOCAL
#include "debug.h"
#else
#define debug(...) 42
#endif

const int N = 2e5 + 5, LG = 18, MAX = 3600005;

int n, k, m;
int lst[N], c[N], dep[N], pr[LG][N], id[LG][N], low[MAX], num[MAX], cnt[MAX], lab[MAX];
vector<int> tree[N], g[MAX];

void dfs(int u) {
  for (int v : tree[u]) {
    if (v != pr[0][u]) {
      pr[0][v] = u;
      id[0][v] = c[u];
      for (int i = 1; i < LG; ++i) {
        id[i][v] = ++m;
        pr[i][v] = pr[i - 1][pr[i - 1][v]];
        g[m].push_back(id[i - 1][v]);
        g[m].push_back(id[i - 1][pr[i - 1][v]]);
      }
      dep[v] = dep[u] + 1;
      dfs(v);
    }
  }
}

int lca(int u, int v) {
  if (dep[u] < dep[v]) {
    swap(u, v);
  }
  for (int j = LG - 1; ~j; --j) {
    if (dep[u] - (1 << j) >= dep[v]) {
      u = pr[j][u];
    }
  }
  if (u == v) {
    return u;
  }
  for (int j = LG - 1; ~j; --j) {
    if (pr[j][u] != pr[j][v]) {
      u = pr[j][u], v = pr[j][v];
    }
  }
  return pr[0][u];
}

void add(int u, int p) {
  int col = c[u];
  for (int i = LG - 1; ~i; --i) {
    if (dep[u] - (1 << i) >= dep[p]) {
      g[col].push_back(id[i][u]);
      u = pr[i][u];
    }
  }
}

int top, timer, scc;
int st[MAX];

void DFS(int u) {
  st[++top] = u;
  low[u] = num[u] = ++timer;
  for (int v : g[u]) {
    if (!num[v]) {
      DFS(v);
      low[u] = min(low[u], low[v]);
    } else {
      low[u] = min(low[u], num[v]);
    }
  }
  if (low[u] == num[u]) {
    ++scc;
    while (1) {
      int v = st[top--];
      num[v] = MAX;
      lab[v] = scc;
      if (v == u) {
        break;
      }
    }
  } 
}

int main() {
  ios::sync_with_stdio(false); cin.tie(nullptr);

  cin >> n >> k; m = k;
  for (int i = 1; i < n; ++i) {
    int u, v; cin >> u >> v;
    tree[u].push_back(v);
    tree[v].push_back(u);
  }  
  for (int i = 1; i <= n; ++i) {
    cin >> c[i];
  }
  dfs(1);
  for (int i = 1; i <= n; ++i) {
    if (lst[c[i]]) {
      int x = lca(i, lst[c[i]]);
      add(i, x);
      add(lst[c[i]], x);
    }
    lst[c[i]] = i;
  }
  for (int i = 1; i <= m; ++i) {
    if (!num[i]) {
      DFS(i);
    }
  }
  for (int i = 1; i <= k; ++i) {
    ++cnt[lab[i]];
  }
  vector<int> ver(m);
  iota(ver.begin(), ver.end(), 1);
  sort(ver.begin(), ver.end(), [&](int i, int j) {
    return lab[i] < lab[j];
  });
  int res = MAX;
  for (int i = 1, j = 0; i <= scc; ++i) {
    bool out = 0;
    while (j < m && lab[ver[j]] == i) {
      for (int k : g[ver[j]]) {
        if (lab[k] != i && cnt[lab[k]]) {
          out = 1;
        }
      }
      j++;
    }
    if (out) {
      cnt[i] = 1;
    } else if (cnt[i]) {
      res = min(res, cnt[i] - 1);
    }
  }
  cout << res;
  return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...