zoukankan      html  css  js  c++  java
  • 「一本通 4.4 例 2」暗的连锁 POJ3417 LOJ10131

    树上边的差分,给每个点赋值为0,对于非树边(x,y)x,y权值+1,lca(x,y)-=2,再dfs

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #define MN 200050
    using namespace std;
    int n, m, cnt, head[MN], ans[MN], dfn[MN], num[MN];
    int f[MN][21];
    int lg[MN];
    struct tu {
        int v, nxt;
    } e[MN];
    void add(int u, int v) {
        e[++cnt].v = v;
        e[cnt].nxt = head[u];
        head[u] = cnt;
    }
    void dfs(int now, int fa) {
        dfn[now] = dfn[fa] + 1;
        f[now][0] = fa;
        for (int i = 1; (1 << i) <= dfn[now]; i++) f[now][i] = f[f[now][i - 1]][i - 1];
        for (int i = head[now]; i; i = e[i].nxt) {
            if (e[i].v != fa)
                dfs(e[i].v, now);
        }
    }
    int lca(int x, int y) {
        if (dfn[x] < dfn[y])
            swap(x, y);
        while (dfn[x] > dfn[y]) {
            x = f[x][lg[dfn[x] - dfn[y]]];
        }
        if (x == y)
            return x;
        for (int k = lg[dfn[x]]; k >= 0; k--)
            if (f[x][k] != f[y][k])
                x = f[x][k], y = f[y][k];
        return f[x][0];
    }
    void search(int now, int fa) {
        ans[now] = num[now];
        for (int i = head[now]; i; i = e[i].nxt) {
            if (e[i].v != fa) {
                search(e[i].v, now);
                ans[now] += ans[e[i].v];
            }
        }
    }
    int main() {
        int sum = 0;
        scanf("%d%d", &n, &m);
        lg[0] = -1;
        for (int i = 1; i <= n; i++) lg[i] = lg[i >> 1] + 1;
        for (int i = 1; i <= n - 1; i++) {
            int a, b;
            scanf("%d%d", &a, &b);
            add(a, b);
            add(b, a);
        }
        dfs(1, 0);
        for (int i = 1; i <= m; i++) {
            int a, b;
            scanf("%d%d", &a, &b);
            num[a]++;
            num[b]++;
            num[lca(a, b)] -= 2;
        }
        search(1, 0);
        for (int i = 2; i <= n; i++) {
            if (!ans[i])
                sum += m;
            if (ans[i] == 1)
                sum++;
        }
        printf("%d", sum);
    
        return 0;
    }
    
     

    若有错误请指出

    缘分让我们相遇乱世以外, 命运却要我们危难中相爱。 也许未来遥远在光年之外, 我愿守候未知里为你等待。
  • 相关阅读:
    iOS多线程之NSThread详解
    iOS中NSScanner 的用法
    自己的第一篇博客
    useradd与adduser的区别
    drop、truncate和delete的区别
    开启ipv6支持
    linux主机hang住echo 0 > /proc/sys/kernel/hung_task_timeout_secs disables this message
    xfs文件系统修复方法https://blog.csdn.net/yuanfang_way/article/details/78700089
    mysql表死锁查询
    系统丢包net.netfilter.nf_conntrack_max 超限查看
  • 原文地址:https://www.cnblogs.com/zw130-lzr-blogs/p/10967890.html
Copyright © 2011-2022 走看看