树学习笔记——处理边权

零、前言(胡说八道)

众所周知,在一棵已经有根的树上,处理点权是非常容易的,只要另外开一个数组记录每个点对应的权值即可。

但我们在学习有根树的过程中,经常会遇到某些题目给定了权值,给定的是边权,而不是点权。导致后面的算法处理这里时可能出现一些困难。(我在这里翻车了\(n\) 次)

因此,就出现了一些奇妙的方法,轻松存储或处理了边权。

一、方法

1、邻接表(链式前向星)

和图的邻接表一样,可以直接解决问题。

没啥可说的(逃)

ex:(核心代码)

int cnt = 0, head[105];
struct node{
      int u, v, w, next;
}ed[505];
void add(int uu, int vv, int ww)
{
      cnt++;
      ed[cnt].u = uu; //父节点
      ed[cnt].v = vv; //子节点
      ed[cnt].w = ww; //这条边权值
      ed[cnt].next = head[uu];
      head[uu] = cnt;
}

2、vector + 结构体大法好!

\(vector\) 的类型并不只能是整型,当然也可以是结构体!

先独立写一个结构体,里面封装两个:一个节点,一个边权即可。(另一个节点是那一维)

每次存边的时候存\(2\) 个数。

ex:

struct node{
      int v, w;
};
vector <node> g[105]; //这里的类型改成那个结构体的名称
...
int main()
{
      int n, m;
      cin >> n >> m;
      ...
      for(int i = 1; i <= m; i++)
      {
            int x, y, z;
            cin >> x >> y >> z;
            g[x].push_back({y, z});//注意这里要与结构体内封装的变量个数一致,并且外面要加大括号
            g[y].push_back({x, z});//因为这时两个节点并没有确立父子关系,所以两边全加
      }
}

3、边权-->点权

我们已经知道了两点的父子关系,

那么,我们可以根据题目要求,把那条边权挂到父节点子节点上。

比如,如果是求从根开始的树上前缀和,那就要把边权挂到子节点上去,这样对计算出的结果不会有影响。但如果是求从叶子节点开始的子树前缀和,那就要把边权挂到父节点上去。

代码不小心被吞掉了~

posted @ 2021-02-03 15:32  panjx  阅读(291)  评论(0编辑  收藏  举报