ABC 368

Table of Contents

D - Minimum Steiner Tree

https://atcoder.jp/contests/abc368/tasks/abc368_d

$V_1$ から DFS して、子または自身が $V_i$ に含まれていればそのノードを残す。

vvint graph;
vint visited;
set<int> memo;
int ans = 0;

bool dfs(int now) {
    bool res = false;
    if (memo.count(now))
        res = true;

    for (int nx : graph[now]) {
        if (visited[nx])
            continue;
        visited[nx] = 1;

        bool x = dfs(nx);
        res = res || x;

        // short-circuit で以下のよう書くと dfs が実行されない
        // res = res || dfs(nx)
    }

    if (res)
        ans++;
    return res;
}

void solve() {
    int n, k;
    cin >> n >> k;
    graph = vvint(n);
    rep(i, n - 1) {
        int u, v;
        cin >> u >> v;
        u--, v--;
        graph[u].push_back(v);
        graph[v].push_back(u);
    }

    vint nodes(k);
    rep(i, k) {
        cin >> nodes[i];
        nodes[i]--;
    }

    for (int x : nodes)
        memo.insert(x);

    visited = vint(n, 0);
    visited[nodes[0]] = 1;

    dfs(nodes[0]);
    cout << ans << endl;
}