2022-11-04:给定一个正数n,表示有多少个节点
给定一个二维数组edges,表示所有无向边
edges[i] = {a, b} 表示a到b有一条无向边
edges一定表示的是一个无环无向图,也就是树结构
每个节点可以染1、2、3三种颜色。
要求 : 非叶节点的相邻点一定要至少有两种和自己不同颜色的点。
返回一种达标的染色方案,也就是一个数组,表示每个节点的染色状况。
1 <= 节点数量 <= 10的5次方。
来自米哈游。

答案2022-11-04:

生成图,选一个头节点,深度优先染色。

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

use std::{iter::repeat, vec};

use rand::Rng;
fn main() {
let nn: i32 = 100;
let test_time: i32 = 1000;
println!("测试开始");
for i in 0..test_time {
let n = rand::thread_rng().gen_range(0, nn) + 1;
let mut edges = random_edges(n);
let mut ans = dye(n, &mut edges);
if !right_answer(n, &mut edges, &mut ans) {
println!("出错了!{}", i);
break;
}
}
println!("测试结束");
} // 1 2 3 1 2 3 1 2 3
const RULE1: [i32; 3] = [1, 2, 3]; // // 1 3 2 1 3 2 1 3 2
const RULE2: [i32; 3] = [1, 3, 2]; fn dye(n: i32, edges: &mut Vec<Vec<i32>>) -> Vec<i32> {
let mut graph: Vec<Vec<i32>> = vec![];
// 0 : { 2, 1 }
// 1 : { 0 }
// 2 : { 0 }
for _i in 0..n {
graph.push(vec![]);
}
for edge in edges.iter() {
// 0 -> 2
// 1 -> 0
graph[edge[0] as usize].push(edge[1]);
graph[edge[1] as usize].push(edge[0]);
}
// 选一个头节点!
let mut head = -1;
for i in 0..n {
if graph[i as usize].len() >= 2 {
head = i;
break;
}
}
// graph
// head
let mut colors: Vec<i32> = repeat(0).take(n as usize).collect();
if head == -1 {
// 两个点,互相连一下
// 把colors,所有位置,都设置成1
colors = repeat(1).take(n as usize).collect();
} else {
// dfs 染色了!
colors[head as usize] = 1;
let h = graph[head as usize][0];
dfs(&mut graph, h, 1, &RULE1, &mut colors);
for i in 1..graph[head as usize].len() as i32 {
let h = graph[head as usize][i as usize];
dfs(&mut graph, h, 1, &RULE2, &mut colors);
}
}
return colors;
} // 整个图结构,都在graph
// 当前来到的节点,是head号节点
// head号节点,在level层
// 染色的规则,rule {1,2,3...} {1,3,2...}
// 做的事情:以head为头的整颗树,每个节点,都染上颜色
// 填入到colors数组里去
fn dfs(graph: &mut Vec<Vec<i32>>, head: i32, level: i32, rule: &[i32; 3], colors: &mut Vec<i32>) {
colors[head as usize] = rule[(level % 3) as usize];
for next in graph[head as usize].clone().iter() {
if colors[*next as usize] == 0 {
dfs(graph, *next, level + 1, rule, colors);
}
}
} // 为了测试
// 生成无环无向图
fn random_edges(n: i32) -> Vec<Vec<i32>> {
let mut order: Vec<i32> = repeat(0).take(n as usize).collect();
for i in 0..n {
order[i as usize] = i;
}
let mut i = n - 1; while i >= 0 {
order.swap(i as usize, rand::thread_rng().gen_range(0, i + 1) as usize);
i -= 1;
}
let mut edges: Vec<Vec<i32>> = repeat(repeat(0).take(2).collect())
.take((n - 1) as usize)
.collect();
for i in 1..n {
edges[(i - 1) as usize][0] = order[i as usize];
edges[(i - 1) as usize][1] = order[rand::thread_rng().gen_range(0, i) as usize];
}
return edges;
} // 为了测试
fn right_answer(n: i32, edges: &mut Vec<Vec<i32>>, colors: &mut Vec<i32>) -> bool {
let mut graph: Vec<Vec<i32>> = vec![];
for _i in 0..n {
graph.push(vec![]);
}
for edge in edges.iter() {
graph[edge[0] as usize].push(edge[1]);
graph[edge[1] as usize].push(edge[0]);
}
let mut has_colors: Vec<bool> = repeat(false).take(4).collect();
let mut i = 0;
let mut color_cnt = 1;
while i < n {
if colors[i as usize] == 0 {
return false;
}
if graph[i as usize].len() <= 1 {
// i号点是叶节点
i += 1;
color_cnt = 1;
continue;
}
has_colors[colors[i as usize] as usize] = true;
for near in graph[i as usize].iter() {
if !has_colors[colors[*near as usize] as usize] {
has_colors[colors[*near as usize] as usize] = true;
color_cnt += 1;
}
}
if color_cnt != 3 {
return false;
}
has_colors = repeat(false).take(4).collect();
i += 1;
color_cnt = 1;
}
return true;
}

执行结果如下:


左神java代码

2022-11-04:给定一个正数n,表示有多少个节点 给定一个二维数组edges,表示所有无向边 edges[i] = {a, b} 表示a到b有一条无向边 edges一定表示的是一个无环无向图,也的更多相关文章

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

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

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

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

  3. 【剑指Offer】面试题04. 二维数组中的查找

    题目 在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 示例: 现 ...

  4. 【剑指 Offer】04.二维数组中的查找

    题目描述 在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. ...

  5. 剑指 Offer 04. 二维数组中的查找

    链接:https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/ 标签:数组.双指针.二分 题目 在一个 n * m ...

  6. 【剑指Offer】04. 二维数组中的查找 解题报告(Java & Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 解题方法 日期 题目地址:https://leetcode-cn.com/ ...

  7. 《剑指offer》面试题04. 二维数组中的查找

    问题描述 在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 示例: ...

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

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

  9. 剑指offer-特定二维数组中查找一个元素是否存在-二分搜索-二维数组

    int [][] array ={ {1,2,8,9}, {2,4,9,12}, {4,7,10,13}, {6,8,11,19} }; 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都 ...

  10. 【c语言】二维数组中的查找,杨氏矩阵在一个二维数组中,每行都依照从左到右的递增的顺序排序,输入这种一个数组和一个数,推断数组中是否包括这个数

    // 二维数组中的查找,杨氏矩阵在一个二维数组中.每行都依照从左到右的递增的顺序排序. // 每列都依照从上到下递增的顺序排序.请完毕一个函数,输入这种一个数组和一个数.推断数组中是否包括这个数 #i ...

随机推荐

  1. Jsp 总结

    JSP中的include的两种用法 1.两种用法 <@inlcude file ="header.jsp"/> 此时引入的是静态的jsp文件,它将引入的jsp中的源代码 ...

  2. Android进度表示

    在连接上数据库之后,一切都变得简单了呢! 开心,很轻松地就能够将APP里面的相关内容写完啦! 尝试了好久的连接Mysql数据库,最后还是没有成功: 虽然Android studio里面自带的SQLit ...

  3. CF1037H Security题解

    根据字典序的定义,位置大的大于长度长的,长度长的大于长度短的. 所以我们贪心,先追求长度长的,再追求后面的位置大的,再追求前面的位置大的. 我们要一个能遍历子串的结构,就选 SAM 得了. 还有个限制 ...

  4. 《操作系统导论》读书笔记1——CPU虚拟化,进程

    系列文章目录和关于我 一丶CPU的虚拟化 一个桃子,我们称之为物理(physical)桃子.但有很多想吃这个桃子的 人,我们希望向每个想吃的人提供一个属于他的桃子,这样才能皆大欢喜.我们把给每个 人的 ...

  5. Go语言:利用 TDD 驱动开发测试 学习结构体、方法和接口

    环境安装: (新手向)在Linux中使用VScode编写 "Hello,world"程序,并编写测试-Ubuntu20.4 上一篇相关随笔: Go语言:利用 TDD 测试驱动开发帮 ...

  6. Kafka 之 HW 与 LEO

    更多内容,前往 IT-BLOG HW(High Watermark):俗称高水位,它标识了一个特定的消息偏移量(offset),消费者只能拉取到这个 offset 之前的消息.分区 ISR 集合中的每 ...

  7. mysql根据多列去除重复数据bing 并保留id最小的一项

    首先我的数剧是这样的: 我想根据name1.relation和name2判断如果重复的话删除重复的数据且保留id最小的一条数据,于是写了下面的sql语句 DELETE FROM star_relati ...

  8. 推荐三款 Mac 上的理财神器 iCompta、Rublik、UctoX

    今天推荐三款理财神器,像个人的话可以使用 iCompta(个人财务管理)一款软件就好了,但有些朋友可能有关注汇率的需求,可以使用 Rublik(汇率动态),还有一些小伙伴可能有自己的公司等原因财务量较 ...

  9. JavaScript中计时器requestAnimationFrame、setTimeout、setInterval、setImmediate的使用和区别

    在JavaScript中,我们经常使用requestAnimationFrame.setTimeout.setInterval和setImmediate来控制代码的执行时机.它们各有特点和适用场景: ...

  10. opengl helloworld vscode 通过glfw 绘制三角形

    opengl helloworld vscode 调用glfw 绘制三角形 目录 opengl helloworld vscode 调用glfw 绘制三角形 打开 glfw.org, 我下的64 目录 ...