제출 #545531

#제출 시각아이디문제언어결과실행 시간메모리
545531LucaDantasMergers (JOI19_mergers)C++17
0 / 100
163 ms66448 KiB
#include <bits/stdc++.h>
using namespace std;

constexpr int maxn = 5e5+10, logn = 21;

struct DSU {
    int pai[maxn], peso[maxn], sz;
    DSU(int n = 0, int _sz = 0) {
        sz = _sz;
        for(int i = 1; i <= n; i++)
            pai[i] = i, peso[i] = 1;
    }
    int find(int x) { return pai[x] == x ? x : pai[x] = find(pai[x]); }
    void join(int a, int b) {
        a = find(a), b = find(b);
        if(a == b) return;
        --sz;
        if(peso[a] < peso[b])
            swap(a, b);
        pai[b] = a;
        peso[a] += peso[b];
    }
} dsu;

vector<int> g[maxn];

int p[maxn][logn], depth[maxn];

void pre(int u) {
    for(int v : g[u]) if(v != p[u][0]) {
        p[v][0] = u;
        depth[v] = depth[u]+1;
        pre(v);
    }
}

void build() {
    for(int l = 1; l < logn; l++)
        for(int u = 0; u < maxn; u++)
            p[u][l] = p[p[u][l-1]][l-1];
}

int LCA(int a, int b) {
    if(depth[a] < depth[b])
        swap(a, b); // a é o que sobe
    for(int l = logn-1; l >= 0; l--)
        if(depth[a] - (1 << l) >= depth[b])
            a = p[a][l];
    if(a == b) return a;
    for(int l = logn-1; l >= 0; l--)
        if(p[a][l] != p[b][l])
            a = p[a][l], b = p[b][l];
    return p[a][0];
}

int lca_cor[maxn], lca[maxn], cor[maxn];

void dfs(int u) {
    lca[u] = lca_cor[cor[u]];
    for(int v : g[u]) if(v != p[u][0]) {
        dfs(v);
        if(lca[v] == v) continue;
        dsu.join(cor[u], cor[v]);
        lca[u] = LCA(lca[u], lca[v]);
    }
}

int main() {
    int n, k; scanf("%d %d", &n, &k);
    for(int i = 1, u, v; i < n; i++)
        scanf("%d %d", &u, &v), g[u].push_back(v), g[v].push_back(u);
    pre(1);
    build();

    for(int i = 1; i <= n; i++)
        scanf("%d", &cor[i]);

    for(int i = 1; i <= n; i++) {
        if(!lca_cor[cor[i]])
            lca_cor[cor[i]] = i;
        else
            lca_cor[cor[i]] = LCA(lca_cor[cor[i]], i);
    }

    dsu = DSU(n, k);
    dfs(1);
    printf("%d\n", dsu.sz >> 1);
}

컴파일 시 표준 에러 (stderr) 메시지

mergers.cpp: In function 'int main()':
mergers.cpp:69:20: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   69 |     int n, k; scanf("%d %d", &n, &k);
      |               ~~~~~^~~~~~~~~~~~~~~~~
mergers.cpp:71:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   71 |         scanf("%d %d", &u, &v), g[u].push_back(v), g[v].push_back(u);
      |         ~~~~~^~~~~~~~~~~~~~~~~
mergers.cpp:76:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   76 |         scanf("%d", &cor[i]);
      |         ~~~~~^~~~~~~~~~~~~~~
#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...