zoukankan      html  css  js  c++  java
  • Y(类树形DP)

    Y

     HDU - 4705 

    题意:给你一棵树,n个节点n-1条边(双向),树上任意三个点不在一条路径上,统计这样的三点集合有多少种。

    思路:

      n个节点中任选3个点的方案数为n*(n-1)*(n-2)/6,从中减去三个点在同一条路径上的种类数即为答案。如何找在同一条路径上的方案数呢,就是以固定某一个点,看看他的一个儿子有几个儿子,儿子的儿子个数加上儿子本身,从这些点中选一个,再从剩余的点中选一个,即可以构成三个点在同一条直线上。所有对于固定的这个点x,方案数为sum[son]*(n-sum[x])

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+10;
    vector<int>v[maxn];
    int vis[maxn];
    int a,b;
    ll ans,n,t,son[maxn];
    void dfs(int x)
    {
        vis[x]=1;
        son[x]=1;
        for(int i=0;i<v[x].size();i++)
        {
            int to=v[x][i];
            if(vis[to])
                continue;
            dfs(to);
            son[x]+=son[to];
            ans+=(n-son[x])*son[to]; 
        }
    }
    int main()
    {
        while(~scanf("%lld",&n))
        {
            ans=0;
            memset(son,0,sizeof(son));
            memset(vis,0,sizeof(vis));
            for(int i=0;i<=n;i++)
                v[i].clear();
            for(int i=1;i<n;i++)
            {
                scanf("%d%d",&a,&b);
                v[a].push_back(b); 
                v[b].push_back(a);
            }
            dfs(1);
            t=(n-1)*n*(n-2)/6;
            printf("%lld
    ",t-ans);
        }
    }

    这个题的思路和hdu2376有些像,果然要学着举一反三啊啊啊啊啊啊~~~

  • 相关阅读:
    redis 一主二从三哨兵
    java 调用axis2 webservice
    oracle 自增ID
    yum安装命令的使用方法
    SLES 10安装Oracle10gR2笔记
    信息系统集成资质等级评定条件(暂行)
    ionic imgBase64
    IOS 断点下载
    IOS JSON
    citrix更换vcenter后所需改动几张表
  • 原文地址:https://www.cnblogs.com/1013star/p/9960043.html
Copyright © 2011-2022 走看看