前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >2024-04-21:用go语言,给一棵根为1的树,每次询问子树颜色种类数。 假设节点总数为n,颜色总数为m, 每个节点的颜色,

2024-04-21:用go语言,给一棵根为1的树,每次询问子树颜色种类数。 假设节点总数为n,颜色总数为m, 每个节点的颜色,

作者头像
福大大架构师每日一题
发布2024-04-25 13:27:55
900
发布2024-04-25 13:27:55
举报

2024-04-21:用go语言,给一棵根为1的树,每次询问子树颜色种类数。

假设节点总数为n,颜色总数为m,

每个节点的颜色,依次给出,整棵树以1节点做头,

有k次查询,询问某个节点为头的子树,一共有多少种颜色。

1 <= n, m, k <= 10^5。

答案2024-04-21:

来自左程云。

chatgpt

大体步骤如下:

大体过程描述:

1.数据结构初始化:定义全局变量和数组用来存储图的结构、节点颜色等信息,并初始化相关数组和变量。

2.输入处理:通过预定义的输入数组,按给定格式依次读取节点数n,建立树的连接关系,记录每个节点的颜色。

3.DFS遍历

  • 第一次DFS(dfs1):计算每个节点子树的大小,并标记每个节点的重节点。
  • 第二次DFS(dfs2):处理每个节点的子树,包括处理重节点和非重节点的不同子树,更新颜色计数和子树的颜色种类数。

4.颜色计数:通过add函数和delete函数实现颜色的增加与减少操作,维护当前节点子树中颜色种类的计数。

5.输出查询结果:对于每次查询,按照给定节点进行处理,并输出计算得到的颜色种类数。

时间复杂度:

  • DFS1:对整个树进行一次DFS,时间复杂度为O(n)。
  • DFS2:同样对整个树进行一次DFS,时间复杂度为O(n)。
  • add和delete函数:每个节点至多被遍历4次(每条边两次),因此每次add和delete的时间复杂度为O(n)。
  • 查询:对于每次查询,计算颜色种类数时需要遍历整个子树,时间复杂度为O(n)。

综上,总的时间复杂度为O(n)。

空间复杂度:

  • graph, color, size, heavy, cnt, ans:每个数组的长度为n,因此空间复杂度为O(n)。
  • 其他局部变量:不超过常数大小,可忽略。

综上,总的额外空间复杂度为O(n)。

Go完整代码如下:

代码语言:javascript
复制
package main

import (
    "fmt"
)

var MAXN int = 200005
var graph [][]int
var color []int
var size []int
var heavy []int
var cnt []int
var ans []int
var n, m int

func main() {
    graph = make([][]int, MAXN)
    for i := range graph {
        graph[i] = make([]int, 0)
    }
    color = make([]int, MAXN)
    size = make([]int, MAXN)
    heavy = make([]int, MAXN)
    cnt = make([]int, MAXN)
    ans = make([]int, MAXN)

    inputs := []int{5,
        1, 2,
        1, 3,
        2, 4,
        2, 5,
        1, 2, 2, 3, 3,
        5,
        1,
        2,
        3,
        4,
        5}
    ii := 0

    for ii < len(inputs) {
        n = inputs[ii]
        ii++

        for i := 1; i <= n; i++ {
            graph[i] = make([]int, 0)
        }

        for i := 1; i < n; i++ {
            a := inputs[ii]
            ii++
            b := inputs[ii]
            ii++
            graph[a] = append(graph[a], b)
            graph[b] = append(graph[b], a)
        }

        for i := 1; i <= n; i++ {
            c := inputs[ii]
            ii++
            color[i] = c
        }

        dfs1(1, 0)

        dfs2(1, 0, false)

        m = inputs[ii]
        ii++

        for i := 1; i <= m; i++ {
            q := inputs[ii]
            ii++
            fmt.Println(ans[q])
        }
    }
}

var total int

func dfs1(cur, father int) {
    size[cur] = 1
    for _, next := range graph[cur] {
        if next != father {
            dfs1(next, cur)
            size[cur] += size[next]
            if size[heavy[cur]] < size[next] {
                heavy[cur] = next
            }
        }
    }
}

func dfs2(cur, father int, isHeavy bool) {
    for _, next := range graph[cur] {
        if next != father && next != heavy[cur] {
            dfs2(next, cur, false)
        }
    }

    if heavy[cur] != 0 {
        dfs2(heavy[cur], cur, true)
    }

    add(cur, father, heavy[cur])
    ans[cur] = total

    if !isHeavy {
        delete(cur, father)
        total = 0
    }
}

func add(cur, father, except int) {
    cnt[color[cur]]++
    if cnt[color[cur]] == 1 {
        total++
    }

    for _, next := range graph[cur] {
        if next != father && next != except {
            add(next, cur, except)
        }
    }
}

func delete(cur, father int) {
    cnt[color[cur]]--
    for _, next := range graph[cur] {
        if next != father {
            delete(next, cur)
        }
    }
}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-04-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 福大大架构师每日一题 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 大体步骤如下:
    • 大体过程描述:
      • 时间复杂度:
        • 空间复杂度:
        • Go完整代码如下:
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档