zoukankan      html  css  js  c++  java
  • 【树形dp练习】Y

    题面

    对于给定的树T,计算集合{A,B,C}的数量,其中:
    1、A,B,C是树T的节点
    2、不存在经过A,B,C的简单路径

    分析

    我猜题目叫Y的原因是因为要求的三个点构成一个Y的形状qvq

    先看这个粉色的部分,考虑怎么计算第二部分的答案呢?

    根据组合数学的思想,可以从3,4,8为根的子树内选两个(一个子树内只能选一个),然后再从除了以2为根的子树的其他所有结点中选一个,相乘。

    第一部分的答案就更简单了,就是这个子树的所有小子树的大小的乘积,因为会被三次计算,所以最后除以三

    然而!!

    上面的方法过于复杂,我们可以根据正难则反的思想。计算三个点在一个简单路径上的数量,再用总路径数C(N,3)减去它。

    三个点在一个简单路径:对于有儿子的点,选择他,并在以他为根的子树中选1个和除了他的子树以外的所有点中选1个

    对于无儿子的点,除了他的所有点中选择2个。

    最后因为每条路径被三个点计算了,总简单路径数除以3

    代码

    法一的代码。法二的代码更为简洁,可以自行实现

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ll long long 
    #define N 200010
    ll t,n,p1,p2,cnt;
    ll first[N],siz[N];
    struct email
    {
        ll u,v;
        ll nxt;
    }e[N*4];
    inline void add(ll u,ll v)
    {
        e[++cnt].nxt=first[u];first[u]=cnt;
        e[cnt].u=u;e[cnt].v=v;
    }
    
    inline void init()
    {
        cnt=p1=p2=0;
        memset(siz,0,sizeof(siz));
        memset(first,0,sizeof(first));    
    }
    
    void dfs(ll u,ll fa)
    {
        ll mulv=0;siz[u]=1;
        for(ll i=first[u];i;i=e[i].nxt)
        {
            ll v=e[i].v;
            if(v==fa)continue;
            dfs(v,u);
            mulv+=(siz[u]-1)*(siz[v]);
            siz[u]+=siz[v];
        }
        p1+=mulv*(n-siz[u]);
        for(ll i=first[u];i;i=e[i].nxt)
        {
            ll v=e[i].v;
            if(v==fa)continue;
            p2+=siz[v]*(mulv-siz[v]*(siz[u]-1-siz[v]));
        }
    }
    int main()
    {
        while(scanf("%lld",&n)==1)
        {
            init();
            for(ll i=1;i<n;i++)
            {
                ll u,v;
                scanf("%lld%lld",&u,&v);
                add(u,v);add(v,u);
            }
            dfs(1,0);
            printf("%lld
    ",p1+p2/3);
        }
        return 0;
    }
    “Make my parents proud,and impress the girl I like.”
  • 相关阅读:
    vue+elemnet 实现自定义参数
    css 实现鼠标移上去标题向右滑动的效果
    vue 搜索关键字列表结果高亮显示
    leaflet 实现 测距、测面、清除测量的功能
    js对象的合并
    formdata的使用方法
    fromdata上传多个文件
    3.11formdata的使用
    微信小程序的自定义插件
    3.6
  • 原文地址:https://www.cnblogs.com/NSD-email0820/p/9764985.html
Copyright © 2011-2022 走看看