首页 > 其他分享 >树上dp

树上dp

时间:2023-07-08 16:56:42浏览次数:39  
标签:nxt head int cnt v2 树上 dp size

树上dp

树的存储

邻接表:将这个点的所有直接子节点存储在以这个点为开头的链表上

https://oi-wiki.org/graph/save/#邻接表

void add(int u,int v)// 添加一条边u->v
{
        cnt++;
        nxt[cnt]=head[u];
        head[u]=cnt;
        to[cnt]=v;

}
void solve(int u)
{
        f[u][1]=h[u];
        for (int i = head[u]; ~i; i = nxt[i]) 
        {  // ~i 表示 i != -1
                int v = to[i];
        }
}
        memset(head,-1,sizeof head);
换根dp
代码源 距离和

size[i]表示以i为根的子树上有多少个点,f[i]表示i到子树中其他所有点的距离和

size[i]=∑size(j)+1 j∈son(i)

假设j是i的直接儿子,以j为根的子树对i的贡献为f[j]+size[j]

f[i]=∑(f[j]+size[j])=∑(f[j])+size[i]-1

v[i]表示i点的父亲作为它子树时对i号点的贡献

当i号点作为父亲时 ,1号点作为子树时提供的贡献

v[i]=f[1]-f[i]-size[i]+n-size[i]

f[1]-f[i]-size[i]表示除去i号点及其子树剩下的部分

当根从x变成儿子y时

v[y]=v[x]+f[x]-f[y]-size[y]+n-size[y]//

v[x]+f[x] x为根时所有点到他的距离和

f[y]+size[y] y为子树时的贡献

n-size[y] x子树中点的个数

代码



#include<iostream>
#include<cstring>
using namespace std;
const int N=1e5+10;
int nxt[N],head[N],to[N];
int cnt=-1;
#define rep(i,a,n) for(int i=a;i<=n;i++)
int sz[N],f[N],v[N];//节点数,所有子树中的边数和,父节点变成子节点后的贡献
bool b[N];
	int n;

void add(int u, int v) {// 添加一条边u->v
  nxt[++cnt] = head[u];  // 当前边的后继
  head[u] = cnt;         // 起点 u 的第一条边
  to[cnt] = v;           // 当前边的终点
}

void up(int u)
{
	sz[u]=1;
	b[u]=true;
	for(int i=head[u];~i;i=nxt[i])
	{
		int v=to[i];
		if(!b[v])
		{
			up(v);
			sz[u]+=sz[v];
			f[u]+=f[v];
		}

	}
	f[u]+=sz[u]-1;
}//size f

void down(int u)
{
	b[u]=true;
	for(int i=head[u];~i;i=nxt[i])
	{
		int v2=to[i];
		if(!b[v2])
		{
			v[v2]=v[u]+f[u]-f[v2]-sz[v2]+n-sz[v2];
			down(v2);
		}
	}
}//v


int main()
{
	cin>>n;
	memset(head,-1,sizeof head);
	rep(i,1,n-1)
	{
		int u,v;
		cin>>u>>v;
		add(u,v);
		add(v,u);
	}
	memset(b,false,sizeof b);
	up(1);
	memset(b,false,sizeof b);
	down(1);
	rep(i,1,n)cout<<v[i]+f[i]<<endl;
}

标签:nxt,head,int,cnt,v2,树上,dp,size
From: https://www.cnblogs.com/ying-tu/p/17537389.html

相关文章

  • 「升维打击」- 高维前缀和与 SOSDP
    高维前缀和众所周知,一维前缀和即\(s_i=\sum\limits_{p=1}^ia_p\),二维前缀和则是通过容斥原理来求:由图,显然可以得到\(s_{i,j}=a_{i,j}+s_{i-1,j}+s_{i,j-1}+s_{i-1,j-1}\)。那么,同理推到三维,可以得到\(s_{i,j,k}=a_{i,j,k}+s_{i-1,j,k}+s_{i,j-1,k}+s_{i,j,k-1}-s_{i-1,j-......
  • Wordpress:如何更改Elementor绑定的网站?
    在使用Wordpress做网站的过程中,需要用到Elementor付费版进行优化网站,一般是绑定一个网站后,要想新建另一个网站,基础版不支持多个绑定,那么如何进行改绑呢?1.进入Elementor后台,选择Subscriptions >>>选择已绑定的项,点击右下角ManageThissubscription  2.点击网站后面的锁......
  • CF1842E Tenzing and Triangle - 线段树优化 dp -
    题目链接:https://codeforces.com/contest/1842/problem/E题解:首先,如果两个等腰三角形相交了,那答案肯定不会更优。因此不会相交。先考虑一个\(n^2\)的dp:设\(dp_i\)表示考虑到\(x=i\)时的最小代价,首先可以先都加一个\(\sumc_i\),这样只需要考虑三角形覆盖范围内的\(c_i......
  • 网安周报|黑客利用未修补的WordPress插件缺陷来创建秘密管理员帐户
    网安周报是棱镜七彩推出的安全资讯专栏,旨在通过展示一周内发生的与开源安全、软件供应链安全相关攻击事件,让用户了解开源及软件供应链威胁,提高对安全的重视,做好防御措施。1、黑客利用未修补的WordPress插件缺陷来创建秘密管理员帐户来百度APP畅享高清图片终极会员插件中未修补的关......
  • BZOJ 4247: 挂饰 背包dp
    4247:挂饰TimeLimit: 10Sec  MemoryLimit: 256MBSubmit: 999  Solved: 387[Submit][Status][Discuss]DescriptionJOI君有N个装在手机上的挂饰,编号为1...N。JOI君可以将其中的一些装在手机上。JOI君的挂饰有一些与众不同——其中的一些挂饰附有可以挂其他挂件......
  • BZOJ 1415: [Noi2005]聪聪和可可 期望dp
    1415:[Noi2005]聪聪和可可TimeLimit: 10Sec  MemoryLimit: 162MBSubmit: 1682  Solved: 991[Submit][Status][Discuss]DescriptionInput数据的第1行为两个整数N和E,以空格分隔,分别表示森林中的景点数和连接相邻景点的路的条数。第2行包含两个整数C和M,以空格分......
  • BZOJ 1042:[HAOI2008]硬币购物 容斥原理 背包dp
    1042:[HAOI2008]硬币购物TimeLimit: 10Sec  MemoryLimit: 162MBSubmit: 2505  Solved: 1505[Submit][Status][Discuss]Description硬币购物一共有4种硬币。面值分别为c1,c2,c3,c4。某人去商店买东西,去了tot次。每次带di枚ci硬币,买si的价值的东西。请问每次......
  • BZOJ 1725: [Usaco2006 Nov]Corn Fields牧场的安排 状压dp
    1725:[Usaco2006Nov]CornFields牧场的安排TimeLimit: 5Sec  MemoryLimit: 64MBSubmit: 698  Solved: 489[Submit][Status][Discuss]DescriptionFarmerJohn新买了一块长方形的牧场,这块牧场被划分成M列N行(1<=M<=12;1<=N<=12),每一格都是一块正方形的土地。FJ......
  • BZOJ 1915: [Usaco2010 Open]奶牛的跳格子游戏 单调队列优化dp
    1915:[Usaco2010Open]奶牛的跳格子游戏TimeLimit: 4Sec  MemoryLimit: 64MBSubmit: 281  Solved: 110[Submit][Status][Discuss]Description奶牛们正在回味童年,玩一个类似跳格子的游戏,在这个游戏里,奶牛们在草地上画了一行N个格子,(3<=N<=250,000),编号为1..N......
  • 概率/期望dp刷题整理
    Bagofmice题意:有w只白鼠和b只黑鼠,公主和龙轮流抓老鼠,其中龙每抓一只老鼠就会有一只未被抓住的老鼠逃走,先抓到一只白鼠的获胜,问公主获胜的概率是多少Solution令dp[i][j]表示还剩i只白鼠和j只黑鼠时公主获胜的概率如果公主直接抓住一只白鼠,获胜的概率是\[\frac{i}{i+j}\]如......