Submission #233265

#TimeUsernameProblemLanguageResultExecution timeMemory
233265AlexLuchianovMergers (JOI19_mergers)C++14
24 / 100
190 ms58840 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 = 500000; 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...