Submission #233264

#TimeUsernameProblemLanguageResultExecution timeMemory
233264AlexLuchianovMergers (JOI19_mergers)C++14
24 / 100
161 ms32240 KiB
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>

using namespace std;

using ll = long long;
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MAX(a, b) (((a) < (b)) ? (b) : (a))

int const nmax = 100000;
int const lgmax = 20;

vector<int> g[1 + nmax];
int far[1 + lgmax][1 + nmax];
int level[1 + nmax];

void dfs(int node, int parent){
  level[node] = level[parent] + 1;
  far[0][node] = parent;
  for(int h = 0; h < g[node].size(); h++){
    int to = g[node][h];
    if(to != parent)
      dfs(to, node);
  }
}

void computefar(int n){
  for(int h = 1; h <= lgmax; h++)
    for(int i = 1;i <= n; i++)
      far[h][i] = far[h - 1][far[h - 1][i]];
}
int getlca(int x, int y){
  if(level[x] < level[y])
    swap(x, y);
  for(int h = lgmax; 0 <= h; h--)
    if(level[y] + (1 << h) <= level[x])
      x = far[h][x];
  if(x == y)
    return x;
  for(int h = lgmax; 0 <= h; h--)
    if(far[h][x] != far[h][y]){
      x = far[h][x];
      y = far[h][y];
    }
  return far[0][x];
}

class Dsu{
private:
  vector<int> mult;
public:
  Dsu(int n){
    mult.resize(1 + n);
    for(int i = 1;i <= n; i++)
      mult[i] = i;
  }
  int jump(int x){
    if(mult[x] != x)
      mult[x] = jump(mult[x]);
    return mult[x];
  }
  bool unite(int gala, int galb){
    gala = jump(gala);
    galb = jump(galb);
    if(gala == galb)
      return 0;
    mult[gala] = galb;
    return 1;
  }
};
int frec[1 + nmax];

void markpath(int x, int y, Dsu &dsu){
  int lca = getlca(x, y);
  while(dsu.unite(lca, x) == 1)
    x = far[0][x];
  while(dsu.unite(lca, y) == 1)
    y = far[0][y];

}

set<int> tree[1 + nmax];
int edge[1 + nmax][2];

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

  int n, k;
  cin >> n >> k;
  for(int i = 1;i < n; i++){
    int x, y;
    cin >> x >> y;
    g[x].push_back(y);
    g[y].push_back(x);
    edge[i][0] = x;
    edge[i][1] = y;
  }
  dfs(1, 0);

  computefar(n);
  Dsu dsu(n);
  for(int i = 1;i <= n; i++){
    int val;
    cin >> val;
    if(0 < frec[val])
      markpath(frec[val], i, dsu);
    frec[val] = i;
  }


  for(int i = 1;i < n; i++){
    int x = dsu.jump(edge[i][0]);
    int y = dsu.jump(edge[i][1]);
    if(x != y){
      tree[x].insert(y);
      tree[y].insert(x);
    }
  }

  int leafs = 0;
  for(int i = 1; i <= n; i++)
    leafs += (tree[i].size() == 1);

  if(leafs <= 1)
    cout << 0;
  else
    cout << (leafs + 1) / 2;
  return 0;
}

Compilation message (stderr)

mergers.cpp: In function 'void dfs(int, int)':
mergers.cpp:24:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for(int h = 0; h < g[node].size(); h++){
                  ~~^~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...