首页 > 其他分享 >树的点权

树的点权

时间:2022-11-07 19:35:50浏览次数:49  
标签:每行 int 点权 dfs1 maxn addedge

问题描述

给定一棵有n个点的树(点的编号为1~n),根为1,点有点权,设点i的初始值为0,给出q个操作,每个操作给出两个点和一个值,u,v,t,表示将u到v的路径上的所有点加t,输出所有操作后每个点的点权,。

输入格式

第一行输入两个整数n,q表示树的点的数目与操作次数

下面n-1行,每行两个整数x,y表示边的信息

下面q行,每行三个整数u,v,t表示将u到v的路径上的所有点加t

输出格式

n行,每行表示点i的权值

样例

in

5 5

1 2

1 3

2 4

2 5

1 5 1

2 5 10

3 4 3

2 4 4

1 2 4

out

8

22

3

7

11

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
struct node{
	int to;
	int nxt;
}E[maxn<<1];
int h[maxn],w[maxn],dep[maxn],f[maxn][25],lg[maxn],etot;
void addedge(int x,int y)
{
	E[++etot].to=y;
	E[etot].nxt=h[x];
	h[x]=etot;
}
void dfs(int u,int fa)
{
	dep[u]=dep[fa]+1;
	f[u][0]=fa;
	for (int i=1;(1<<i)<=dep[u];i++)
	{
		f[u][i]=f[f[u][i-1]][i-1];
	}
	for (int i=h[u];i;i=E[i].nxt)
	{
		int v=E[i].to;
		if (v!=fa)
		{
			dfs(v,u);
		}
	}
}
int lca(int x,int y)
{
	if (dep[x]<dep[y]) swap(x,y);
	int d=dep[x]-dep[y];
	while(d)
	{
		int k=lg[d];
		x=f[x][k];
		d=d-(1<<k);
	}	
	if (x==y) return x;
	for (int i=lg[dep[x]];i>=0;i--)
	{
		if (f[x][i]!=f[y][i])
		{
			x=f[x][i];
			y=f[y][i];
		} 
	}
	return f[x][0];
}
void dfs1(int u,int f)
{
	for (int i=h[u];i;i=E[i].nxt)
	{
		int v;
		v=E[i].to;
		if (v!=f)
		{
			dfs1(v,u);
			w[u]+=w[v];	
		}
	}
}
int main()
{
	int n,q;
	cin>>n>>q;
	for (int i=1;i<n;i++)
	{
		int x,y;
		cin>>x>>y;
		addedge(x,y);
		addedge(y,x);
	}
	dfs(1,0);
	for (int i=1;i<=q;i++)
	{
		int x,y,t;
		cin>>x>>y>>t;
		int l=lca(x,y);
		w[x]+=t;
		w[y]+=t;
		w[l]-=t;
		w[f[l][0]]-=t;
	}
	dfs1(1,0);
	for (int i=1;i<=n;i++)
	{
		cout<<w[i]<<endl;
	}
}

  

标签:每行,int,点权,dfs1,maxn,addedge
From: https://www.cnblogs.com/smghj/p/16867143.html

相关文章