zoukankan      html  css  js  c++  java
  • 【每日一题】16.Treepath (LCA + DP)

    补题链接:Here

    题意总结:寻找有多少条两个点之间偶数路径

    看完题,很容易想到在树型中,同一层的节点必然是偶数路径到达,还有就是每隔两层的节点一样可以到达,所以我就理所应当的写了如下代码

    using ll    = long long;
    const int N = 1e5 + 10;
    vector<int> e[N], deg(N);
    int dep[N], Siz[N];
    int Mdep = -1;
    void dfs(int u, int fa) {
        for (int v : e[u]) {
            if (v == fa) continue;
            dep[v] = dep[u] + 1;
            Mdep   = max(Mdep, dep[v]);
            Siz[dep[v]]++;
            dfs(v, u);
        }
    }
    void solve() {
        int n;
        cin >> n;
        for (int i = 1, u, v; i < n; ++i) {
            cin >> u >> v;
            e[u].push_back(v);
            e[v].push_back(u);
            deg[v]++;
        }
        int root = 0;
        for (int i = 1; i <= n && !root; ++i)
            if (!deg[i]) root = i;
        dep[root] = 1, Siz[1] = 1;
        dfs(root, -1);
        ll ans = 0;
        for (int i = 1; i <= Mdep; ++i) {
            ans += Siz[dep[i]] * (Siz[dep[i]] - 1) / 2;
            for (int j = i + 2; j <= Mdep; j += 2)
                ans += Siz[dep[i]] * Siz[dep[j]];
        }
        cout << ans << "
    ";
    }
    

    然后就GG了,通过率为 (0\%)

    WA之后重新理解一下题意,发现这个就是一道枚举起点和终点的 (LCA) ,然后将他们两两组合即可。

    具体的,设 (f[i][0/1])表示以 (i) 为根的子树中,与根节点 (i) 的距离为偶数(0)奇数(1)的点的数量。

    转移方程:(f[u][x] += f[v][x ⊗ 1])

    然后考虑统计答案,以 (u)(LCA) 的两个节点,肯定不能在(u) 的同一个儿子里,所以转移的过程中, (f[u][0/1]) 表示已经当前已经计算过得儿子造成的贡献,对于一个新的儿子 (v)(ans += f[u][0]·f[v][1] + f[u][1]·f[v][0])

    AC 代码:

    using ll    = long long;
    const int N = 1e5 + 10;
    vector<int> e[N];
    ll ans = 0, f[N][2];
    void dfs(int u, int fa) {
        f[u][0] = 1;
        for (int v : e[u]) {
            if (v == fa) continue;
            dfs(v, u);
            ans += f[v][1] * f[u][0];
            ans += f[v][0] * f[u][1];
            f[u][0] += f[v][1];
            f[u][1] += f[v][0];
        }
    }
    void solve() {
        int n;
        cin >> n;
        for (int i = 1, u, v; i < n; ++i) {
            cin >> u >> v;
            e[u].push_back(v), e[v].push_back(u);
        }
        dfs(1, 0);
        cout << ans << '
    ';
    }
    

    顺便一句,以前牛客比赛的数据好水....,连下面这种代码都能过 (60\%)

    using ll = long long;
    ll dp[100010], ans, odd, even, n;
    void solve() {
        cin >> n;
        for (int i = 1, u, v; i < n; ++i) {
            cin >> u >> v;
            dp[v] = dp[u] + 1;
            ans += (dp[v] & 1 ? even++ : ++odd);
        }
        cout << ans << "
    ";
    }
    

    The desire of his soul is the prophecy of his fate
    你灵魂的欲望,是你命运的先知。

  • 相关阅读:
    delphi 属性 参数 新注释
    delphi query阻塞执行 长时间执行sql的解决办法
    FDLocalSQL
    C# Webservice
    vmware的centos 6虚拟机如何共享文件夹?
    tomcat如何配置启动时自动部署webapps下的war包
    tomcat如何配置context的docBase
    windows本地启动tomcat闪退
    jfinal 字节流存储文件以及解、压缩工具类
    java try catch 异常后还会继续执行吗
  • 原文地址:https://www.cnblogs.com/RioTian/p/14713281.html
Copyright © 2011-2022 走看看