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

Posted 福大大架构师每日一题

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2022-11-04:给定一个正数n,表示有多少个节点 给定一个二维数组edges,表示所有无向边 edges[i] = {a, b} 表示a到b有一条无向边 edges一定表示的是一个无环无向图,也相关的知识,希望对你有一定的参考价值。

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一定表示的是一个无环无向图,也的主要内容,如果未能解决你的问题,请参考以下文章

2022-12-14:给定一个正数n, 表示从0位置到n-1位置每个位置放着1件衣服 从0位置到n-1位置不仅有衣服,每个位置还摆着1个机器人 给定两个长度为n的数组,powers和rates pow

2022-05-30:给定一个n*2的二维数组,表示有n个任务。 一个信息是任务能够开始做的时间,另一个信息是任务的结束期限,后者一定大于前者,且数值上都是正数, 你作为单线程的人,不能并行处理任务,

2022-06-25:给定一个正数n, 表示有0~n-1号任务, 给定一个长度为n的数组time,time[i]表示i号任务做完的时间, 给定一个二维数组matrix, matrix[j] = {a,

2023-02-12:给定正数N,表示用户数量,用户编号从0~N-1, 给定正数M,表示实验数量,实验编号从0~M-1, 给定长度为N的二维数组A, A[i] = { a, b, c }表示,用户i报

数值统计

2022-10-03:给定一个正数n,比如6 表示数轴上有 0,1,2,3,4,5,6 <0 或者 >6 的位置认为无法到达 给定两个数字x和y,0<= x,y <= n 表示小人一开始在x的位置,它