2022-09-27:给定一个棵树,
树上每个节点都有自己的值,记录在数组nums里,
比如nums[4] = 10,表示4号点的值是10,
给定树上的每一条边,记录在二维数组edges里,
比如edges[8] = {4, 9}表示4和9之间有一条无向边,
可以保证输入一定是一棵树,只不过边是无向边,
那么我们知道,断掉任意两条边,都可以把整棵树分成3个部分。
假设是三个部分为a、b、c,
a部分的值是:a部分所有点的值异或起来,
b部分的值是:b部分所有点的值异或起来,
c部分的值是:c部分所有点的值异或起来,
请问怎么分割,能让最终的:三个部分中最大的异或值 - 三个部分中最小的异或值,最小。
返回这个最小的差值。
输入:nums = [1,5,5,4,11], edges = [[0,1],[1,2],[1,3],[3,4]]。
输出:9。

答案2022-09-27:

dfn序号。
这道题来自力扣2322。力扣上测试了好几种语言的代码,go语言运行效率是最高,其次是java;rust表现不佳,原因是代码中有复制切片的行为。内存占用go是最低的,rust偏高,原因是代码中有复制切片的行为。
时间复杂度:O(n^2)。
空间复杂度:O(n)。

代码用rust编写。代码如下:

use std::iter::repeat;
fn main() {
let mut nums = vec![1, 5, 5, 4, 11];
let mut edges = vec![vec![0, 1], vec![1, 2], vec![1, 3], vec![3, 4]];
let ans = minimum_score(&mut nums, &mut edges);
println!("ans = {}", ans);
}
const MAX_VALUE: i32 = 1 << 31 - 1;
static mut cnt: i32 = 0; fn minimum_score(nums: &mut Vec<i32>, edges: &mut Vec<Vec<i32>>) -> i32 {
let n = nums.len() as i32;
// 先建立图
// ArrayList<ArrayList<Integer>> graph = new ArrayList<>();
let mut graph: Vec<Vec<i32>> = vec![];
// 4个点,0、1、2、3
// 0 : {}
// 1 : {}
// 2 : {}
// 3 : {}
for _i in 0..n {
graph.push(vec![]);
}
for edge in edges.iter() {
// a,b
// graph.get(a).add(b);
// graph.get(b).add(a);
graph[edge[0] as usize].push(edge[1]);
graph[edge[1] as usize].push(edge[0]);
}
// 无向边组成的无环图
// 为了方便,就认为0是头
// dfn[i] = ?
let mut dfn: Vec<i32> = repeat(0).take(n as usize).collect();
// xor[i] 以i为头的整棵树,整体异或的结果是多少?
let mut xor: Vec<i32> = repeat(0).take(n as usize).collect();
// size[i] 以i为头的整棵树,一共几个点?
let mut size: Vec<i32> = repeat(0).take(n as usize).collect(); unsafe {
cnt = 1;
}
dfs(nums, &mut graph, 0, &mut dfn, &mut xor, &mut size);
let mut ans = MAX_VALUE;
let m = edges.len() as i32;
let mut cut1: i32;
let mut cut2: i32;
let mut pre: i32;
let mut pos: i32;
let mut part1: i32;
let mut part2: i32;
let mut part3: i32;
let mut max: i32;
let mut min: i32;
for i in 0..m {
// i,要删掉的第一条边,i号边
// edges[i][0] edges[i][1] dfn 谁大,谁就是删掉之后的树的头!cut1
// a b cut1
// { a, b}
// 0 1
let a = edges[i as usize][0];
let b = edges[i as usize][1];
cut1 = if dfn[a as usize] < dfn[b as usize] {
b
} else {
a
};
for j in (i + 1)..m {
// j, 要删掉的第二条边,j号边
// { c, d}
// 0 1
let c = edges[j as usize][0];
let d = edges[j as usize][1];
cut2 = if dfn[c as usize] < dfn[d as usize] {
d
} else {
c
};
// cut1,cut2
pre = if dfn[cut1 as usize] < dfn[cut2 as usize] {
cut1
} else {
cut2
};
pos = if pre == cut1 { cut2 } else { cut1 };
// 早 pre 晚 pos
part1 = xor[pos as usize];
// pos为头的树,是pre为头的树的子树!
if dfn[pos as usize] < dfn[pre as usize] + size[pre as usize] {
part2 = xor[pre as usize] ^ xor[pos as usize];
part3 = xor[0] ^ xor[pre as usize];
} else {
// pos为头的树,不是pre为头的树的子树!
part2 = xor[pre as usize];
part3 = xor[0] ^ part1 ^ part2;
}
max = get_max(get_max(part1, part2), part3);
min = get_min(get_min(part1, part2), part3);
ans = get_min(ans, max - min);
}
}
return ans;
} fn get_max<T: Clone + Copy + std::cmp::PartialOrd>(a: T, b: T) -> T {
if a > b {
a
} else {
b
}
} fn get_min<T: Clone + Copy + std::cmp::PartialOrd>(a: T, b: T) -> T {
if a < b {
a
} else {
b
}
}
// 所有节点的值,存在nums数组里
// 整个图结构,存在graph里
// 当前来到的是cur号点
// 请把cur为头,整棵树,所有节点的dfn、size、xor填好!
// 返回!
fn dfs(
nums: &mut Vec<i32>,
graph: &mut Vec<Vec<i32>>,
cur: i32,
dfn: &mut Vec<i32>,
xor: &mut Vec<i32>,
size: &mut Vec<i32>,
) {
// 当前节点了!,
dfn[cur as usize] = unsafe { cnt };
unsafe {
cnt += 1;
}
// 只是来到了cur的头部!
xor[cur as usize] = nums[cur as usize];
size[cur as usize] = 1;
// 遍历所有的孩子!
for next in graph.clone()[cur as usize].iter() {
//有clone,会影响性能
// 只有dfn是0的孩子,才是cur在树中的下级!!!!
if dfn[*next as usize] == 0 {
// cur某个孩子是next dfs(nums, graph, *next, dfn, xor, size);
// next整棵树的异或和,
xor[cur as usize] ^= xor[*next as usize];
// next整棵树的size
size[cur as usize] += size[*next as usize];
}
}
}

执行结果如下:


左神java代码

2022-09-27:给定一个棵树, 树上每个节点都有自己的值,记录在数组nums里, 比如nums[4] = 10,表示4号点的值是10, 给定树上的每一条边,记录在二维数组edges里, 比如ed的更多相关文章

  1. hdu6035 Colorful Tree 树形dp 给定一棵树,每个节点有一个颜色值。定义每条路径的值为经过的节点的不同颜色数。求所有路径的值和。

    /** 题目:hdu6035 Colorful Tree 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6035 题意:给定一棵树,每个节点有一个颜色值.定 ...

  2. ytu 1050:写一个函数,使给定的一个二维数组(3×3)转置,即行列互换(水题)

    1050: 写一个函数,使给定的一个二维数组(3×3)转置,即行列互换 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 154  Solved: 112[ ...

  3. 剑指offer1: 组类型——二维数组中的查找(给定一个数字,查找是否在该数组中)

    1. 思路: 缩小范围 2. 方法: (1)要查找的数字等于数组中的数字,结束查找过程: (2)要查找的数字小于数组中的数字,去除该数字右边的数字,在剩下的数字里查找: (3)要查找的数字大于数组中的 ...

  4. 计算机二级-C语言-程序设计题-190119记录-求出一个二维数组每一列的最小值。

    //编写一个函数:tt指向一个M行N列的二维数组,求出二维数组每列中最小的元素,并依次放入pp所指的一维数组中.二维数组中的数在主函数中赋予. //重难点:求出的是每一列的最小值,这里要注意,学会简化 ...

  5. nRF51800 蓝牙学习 进程记录 2:关于二维数组 执念执战

    前天在玩OLED时想完成一直想弄得一个东西,就是简单的单片机游戏.因为STM32和nRF51822的内存足够,所以就用缓存数组的方法来显示图像(我也不知道术语是啥,反正就是在内存中建立一个128X64 ...

  6. php数组根据某一个键值,把相同键值的合并生成一个新的二维数组

    http://blog.csdn.net/xyzchenxiaolin/article/details/51700485 源数据: $infos = array( array( 'a' => 3 ...

  7. 题目要求:传入数组 内容为[['lisi','男','27'],['wangwu','男',18],['zhaoliu','男','30']],将此二维数组转化为一维数组,创建自定义函数完成

    //自定义函数 function getOne($arr){ $str = ''; //定义空的字符串,用来接收值 foreach ($arr as $key=>$value){ //循环遍历数 ...

  8. PHP如何判断一个数组是一维数组或者是二维数组?用什么函数?

    如题:如何判断一个数组是一维数组或者是二维数组?用什么函数? 判断数量即可 <?php if (count($array) == count($array, 1)) { echo '是一维数组' ...

  9. java怎么定义一个二维数组?

    java中使用 [][] 来定义二维数组 定义数组时也可同时初始化下面是一些例子float[][] numthree; //定义一个float类型的2维数组numthree=new float[5][ ...

  10. PHP如何随机获取一个二维数组中的一个值

    获取一个数组: $awardid_list=pdo_fetchall('select id from '.tablename($this->table_award)); 这是微擎的写法哈,意思就 ...

随机推荐

  1. 关于JDBC的学习

    一.JDBC简介 JDBC是连接java应用程序和数据库之间的桥梁. 什么是JDBC? Java语言访问数据库的一种规范,是一套API. JDBC (Java Database Connectivit ...

  2. TCP通信聊天服务端和客户端(C/C++语言开发)附完整源码

    距离上次学Python写的Python实现简单聊天室已经过去好久了,现在学c++又写了一遍,其实过程差不多,无非是语法的变化,目前仅实现最简单的一对一的通信,然后改就是了,接下来应该是多线程了,话不多 ...

  3. Android笔记--事务处理+数据库版本升级

    事务处理 beginTransaction:开始事务的标志 setTransactionSuccessful:事务成功的标志 endTransaction:结束事务的标志 在上面的图片里面,首先进行事 ...

  4. Python学习笔记--PySpark的相关基础学习(一)

    PySpark包的下载 下载PySpark第三方包: 构建PySpark的执行环境入口对象 PySpark的编程模型 数据输入 对于SparkContext对象里面的成员方法parallelize,支 ...

  5. 使用 Azure OpenAI 打造自己的 ChatGPT

    一.前言 当今的人工智能技术正在不断发展,越来越多的企业和个人开始探索人工智能在各个领域中的应用.其中,在自然语言处理领域,OpenAI 的 GPT 系列模型成为了研究热点.OpenAI 公司的 Ch ...

  6. 图与网络分析—R实现(五)

    四 最大流问题 最大流问题(maximum flow problem),一种网络最优化问题,就是要讨论如何充分利用装置的能力,使得运输的流量最大,以取得最好的效果.最大流问题是一类应用极为广泛的问题, ...

  7. IPv4已正式用尽

    网际协议版本4 (英语:Internet Protocol version 4,缩写:IPv4,又称互联网通信协议第四版)是网际协议开发过程中的第四个修订版本,也是此协议第一个被广泛部署和使用的版本. ...

  8. MySQL之 InnoDB 内存结构

    从MySQL 5.5版本开始默认 使用InnoDB作为引擎,它擅长处理事务,具有自动崩溃恢复的特性,在日常开发中使用非常广泛 下面是官方的InnoDB引擎架构图,主要分为内存结构和磁盘结构两大部分. ...

  9. 11.spring security 认证和授权简单流程了解

    1.总结:昨天主要是对WebSecurityConfigurerAdaptor的三个函数的区分以及了解了spring security的认证和授权流程:再就是动手使用了下thymeleaf和freeM ...

  10. 【实践篇】基于CAS的单点登录实践之路

    作者:京东物流 赵勇萍 前言 上个月我负责的系统SSO升级,对接京东ERP系统,这也让我想起了之前我做过一个单点登录的项目.想来单点登录有很多实现方案,不过最主流的还是基于CAS的方案,所以我也就分享 ...