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\n",t-ans);
    }
}

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

原文地址:https://www.cnblogs.com/1013star/p/9960043.html

时间: 2024-10-18 09:38:50

Y(类树形DP)的相关文章

hdu 4705 Y (树形dp)

Description Input 4 1 2 1 3 1 4 题目的意思是给你一棵树,让你找到所有不在一条路径上的三个点的情况个数.乍一看正向处理比较麻烦,我们从反方向考虑,如果是取在一条路径上的3个点,那又该怎样取呢?我们以Num[rt]表示以rt为根的子树上的节点的个数(包括根节点).选取方法是这样的,先把一个树的树根选上,然后看他每一个亲儿子作为树根时,子树有几个节点(Num[son1],Num[son2],Num[son3]...)对于son1来说,能选取Num[son1]中的任意一点

Average distance(类树形DP)

Average distance HDU - 2376 Given a tree, calculate the average distance between two vertices in the tree. For example, the average distance between two vertices in the following tree is (d 01 + d 02 + d 03 + d 04 + d 12 +d 13 +d 14 +d 23 +d 24 +d 34

UVA1218 Perfect Service(染色问题--树形DP)(好题,通法)

题意:一棵树,进行染色,每个没染色的节点恰好和一个染色的节点相连,求染色的节点最少的个数X(以下均以X代表子问题的解) 思路:树形DP,细化状态,从而对每个节点的每种状态互相递推 这里如何细化状态是难点,而且也是这类难题的共同问题 很容易知道每个节点i至少两个状态:dp[i][0]: i没染上色时以i的子树的X.dp[i][1]: i被染色以i为子树的X 但是仅仅这两个状态无法实现状态转移因为: dp[u][0]=sum(dp[v][0],dp[v][1])+1  (dp[u][0]可以找到状态

【转】【DP_树形DP专辑】【9月9最新更新】【from zeroclock&#39;s blog】

树,一种十分优美的数据结构,因为它本身就具有的递归性,所以它和子树见能相互传递很多信息,还因为它作为被限制的图在上面可进行的操作更多,所以各种用于不同地方的树都出现了,二叉树.三叉树.静态搜索树.AVL树,线段树.SPLAY树,后缀树等等.. 枚举那么多种数据结构只是想说树方面的内容相当多,本专辑只针对在树上的动态规划,即树形DP.做树形DP一般步骤是先将树转换为有根树,然后在树上进行深搜操作,从子节点或子树中返回信息层层往上更新至根节点.这里面的关键就是返回的信息部分,这个也没一般性的东西可讲

P4827 [国家集训队] Crash 的文明世界(第二类斯特林数+树形dp)

传送门 对于点\(u\),所求为\[\sum_{i=1}^ndis(i,u)^k\] 把后面那堆东西化成第二类斯特林数,有\[\sum_{i=1}^n\sum_{j=0}^kS(k,j)\times j!\times{dis(i,u)\choose j}\] \[\sum_{j=1}^nS(k,j)\times j!\sum_{i=0}^k{dis(i,u)\choose j}\] 于是对于每个点只要维护好\(\sum_{i=0}^k{dis(i,u)\choose j}\)就好了 因为\({n

bzoj 2159 Crash 的文明世界 —— 第二类斯特林数+树形DP

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2159 使用公式:\( n^{k} = \sum\limits_{i=0}^{k} S(k,i) * i! * C_{n}^{i} \) 所以维护 \( f[x][i] = \sum\limits_{u\in subtree[x],d=dist(x,u)}^{n} C_{d}^{i} \) 然后利用 \( C_{n}^{m} = C_{n-1}^{m} + C_{n-1}^{m-1} \),

hdu4003 树形dp+分组背包

http://acm.hdu.edu.cn/showproblem.php?pid=4003 Problem Description Humans have discovered a kind of new metal mineral on Mars which are distributed in point‐like with paths connecting each of them which formed a tree. Now Humans launches k robots on

vijos 1313 金明的预算方案 树形DP

描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N元钱就行”.今天一早,金明就开始做预算了,他把想买的物品分为两类:主件与附件,附件是从属于某个主件的,下表就是一些主件与附件的例子:主件 附件电脑 打印机,扫描仪书柜 图书书桌 台灯,文具工作椅 无如果要买归类为附件的物品,必须先买该附件所属的主件.每个主件可以有0个.1个或2个附件.附件不再有从属于自己的附件.金明

树形dp摸瞎历程

树形\(dp\)摸瞎历程 前言: 什么是树形\(dp\)? 简而言之,树形dp,就是在树形结构上的动态规划,由于树形结构具有一定的特点,可以描述比较复杂的关系,再加上树的递归定义,是一种非常合适动规的框架,属于动规中很特殊的一种类型. 如何实现树形\(dp\)? 树形dp的状态表示中,第一位通常是节点编号(代表以该节点为根的子树),大多数时候,我们采用递归的方式实现树形动态规划.对于每个节点x,我们先递归x的所有子节点,并在其子节点上dp,在回溯时,从子节点向节点x进行状态转移. 树形\(dp\