题解 | 计树

计树

https://www.nowcoder.com/practice/e2b6744ec3f94f81aad1c6b8a372b5eb

#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

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

    int n;
    cin >> n;
    vector<vector<int>> edges(n + 1);
    for (int i = 0; i < n - 1; ++i) {
        int u, v;
        cin >> u >> v;
        edges[u].push_back(v);
        edges[v].push_back(u);
    }

    // 构建子节点列表
    vector<int> parent(n + 1, 0);
    vector<vector<int>> children(n + 1);
    queue<int> q;
    q.push(1);
    parent[1] = 0;
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        for (int v : edges[u]) {
            if (v != parent[u]) {
                parent[v] = u;
                children[u].push_back(v);
                q.push(v);
            }
        }
    }

    int k;
    cin >> k;
    vector<int> V(k);
    for (int i = 0; i < k; ++i) {
        cin >> V[i];
    }

    // 标记是否在集合 V 中
    vector<int> is_in_V(n + 1, 0);
    for (int node : V) {
        is_in_V[node] = 1;
    }

    // 计算 s 数组
    vector<long long> s(n + 1, 0);
    vector<pair<int, bool>> stack;
    stack.emplace_back(1, false);
    while (!stack.empty()) {
        auto [node, visited] = stack.back();
        stack.pop_back();
        if (!visited) {
            stack.emplace_back(node, true);
            // 逆序压入子节点以保证处理顺序正确
            for (auto it = children[node].rbegin(); it != children[node].rend(); ++it) {
                stack.emplace_back(*it, false);
            }
        } else {
            long long s_val = is_in_V[node];
            for (int child : children[node]) {
                s_val += s[child];
            }
            s[node] = s_val;
        }
    }

    // 计算 cnt 数组
    vector<long long> cnt(n + 1, 0);
    for (int i = 1; i <= n; ++i) {
        long long total = s[i] * s[i];
        long long sum_child = 0;
        for (int child : children[i]) {
            sum_child += s[child] * s[child];
        }
        cnt[i] = total - sum_child;
    }

    // 输出结果
    for (int i = 1; i <= n; ++i) {
        cout << cnt[i] << ' ';
    }

    return 0;
}

全部评论

相关推荐

05-12 11:09
已编辑
门头沟学院 后端
已注销:没必要放这么多专业技能的描述。这些应该是默认已会的,写这么多行感觉在凑内容。项目这块感觉再包装包装吧,换个名字,虽然大家的项目基本都是网上套壳的,但是你这也太明显了。放一个业务项目,再放一个技术项目。技术项目,例如中间件的一些扩展和尝试。
点赞 评论 收藏
分享
叶扰云倾:进度更新,现在阿里云面完3面了,感觉3面答得还行,基本都答上了,自己熟悉的地方也说的比较细致,但感觉面试官有点心不在焉不知道是不是不想要我了,求阿里收留,我直接秒到岗当阿里孝子,学校那边的房子都退租了,下学期都不回学校,全职猛猛实习半年。这种条件还不诱人吗难道 然后现在约到了字节的一面和淘天的复活赛,外加猿辅导。华为笔试完没动静。 美团那边之前投了个base广州的,把我流程卡麻了,应该是不怎么招人,我直接简历挂了,现在进了一个正常的后端流程,还在筛选,不知道还有没有hc。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务