【备战秋招】每日一题:2023.3.5-米哈游笔试-最长的通讯路径

为了更好的阅读体检,可以查看我的算法学习网
在线评测链接:P1065

题目内容

塔子哥是一位研究者,他在研究网络传输时遇到了一个问题。

他拿到了一张通讯网络的拓扑结构图,其中每条通讯线路被染成了红色或者蓝色。

他想找到一条长度最长的通讯路径,使得路径上相邻的两条线路颜色不同。

输入描述

第一行输入一个正整数 n n n , 代表节点数量。

接下来的 n − 1 n-1 n1 行,每行输入两个正整数 u , v u,v u,v 和一个字符 c h r chr chr ,代表节点 u u u 和节点 v v v 有一条边连接。

若为 ′ R ′ 'R' R 代表这条边是红色, ′ B ′ 'B' B 代表这条边是蓝色。

1 ≤ n ≤ 1 0 5 1\le n \le 10^5 1n105

1 ≤ u , v ≤ n 1\le u,v\le n 1u,vn

保证输入的是一颗树。

输出描述

一个正整数,代表塔子哥可以选择的路径最大长度。

样例

输入

4
1 2 R
2 3 B
3 4 B

输出

2

样例解释

选择 1 − 2 − 3 1-2-3 123 的路径即可。

思路

默认以1为根节点进行 d f s dfs dfs遍历。

d p [ i ] [ 0 ] dp[i][0] dp[i][0]表示在以 i i i为根节点的子树中,且与 i i i的连边为蓝色所有路径中最长的。 d p [ i ] [ 1 ] dp[i][1] dp[i][1]表示以 i i i为根节点的子树中,与 i i i的连边为红色的所有路径中最长的。那从前面两个 d p dp dp我们可以知道以 i i i为根节点,且选择了节点 i i i的最长路径肯定是 d p [ i ] [ 0 ] + d p [ i ] [ 1 ] dp[i][0]+dp[i][1] dp[i][0]+dp[i][1]。那假如我们讨论了所有子树,那么最长路径也肯定知道了。

现在问题在于如何得到所有节点的 d p dp dp值呢。我们发现假如我们知道了一个节点u的所有子节点 v v v d p dp dp值,那么 u u u d p dp dp值也就知道了。因为节点 u u u d p [ u ] [ x ] = m a x ( d p [ v ] [ x ⊕ 1 ] + 1 ) dp[u][x]=max(dp[v][x\oplus 1]+1) dp[u][x]=max(dp[v][x1]+1).所以我们需要先知道所有子节点的 d p dp dp值,再用子节点的 d p dp dp值去更新父节点。这个我们用 d f s dfs dfs去处理。

代码

C++

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 5;
typedef pair<int, int>pii;
int n;
vector<pii>edge[MAXN];
int dp[MAXN][2];
int maxn = 0;
void dfs(int u, int fa){
	if(edge[u].size() == 1 && edge[u][0].first == fa)return;//叶子节点直接return,因为叶子节点的两个dp值肯定是0
	for(int i = 0; i < edge[u].size(); i++){
		pii now = edge[u][i];
		int v = now.first;
		if(v == fa)continue;//如果是父节点,continue,因为我们讨论的是以u为根节点的子树,而u的父节点肯定不属于这颗子树的
		dfs(v, u);//得到子节点答案
		int col = now.second;
		dp[u][col] = max(dp[u][col], dp[v][col ^ 1] + 1);//dp状态转移,用子节点v更新u
		maxn = max(maxn, dp[u][0] + dp[u][1]);//记录答案
	}
}
int main(){
	cin >> n;
	int u, v;
	char ch;
	memset(dp, 0, sizeof dp);//dp初始化
	for(int i = 1; i <= n - 1; i++){
		scanf("%d%d", &u, &v);
		cin >> ch;
		edge[u].push_back({v, ch == 'R'?1:0});
		edge[v].push_back({u, ch == 'R'?1:0});//建图
	}
	dfs(1, 0);
	cout << maxn << endl;
}

Java

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

class TreeNode{
    List<TreeNode> friends;
    List<Character> colors;

    public TreeNode(){
        friends = new ArrayList<TreeNode>();
        colors = new ArrayList<Character>();
    }
}

public class Main {

//    static int result = 0;
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        in.nextLine();
        TreeNode[] tree = new TreeNode[n];
        for(int i = 0; i < n; i++) tree[i] = new TreeNode();
        for(int i=0;i<n-1;i++){
            String[] s = in.nextLine().split(" ");
            int x = Integer.parseInt(s[0])-1;
            int y = Integer.parseInt(s[1])-1;
            char c = s[2].charAt(0);
            if(x>y){
                int temp = x;
                x = y;
                y = temp;
            }
            tree[x].friends.add(tree[y]);
            tree[x].colors.add(c);
            tree[y].friends.add(tree[x]);
            tree[y].colors.add(c);
        }
//        dfs2(tree[0], null);
//        System.out.println(result);
        int result = 0;
        for(int i=0;i<n;i++){
            result = Math.max(result, dfs(tree[i], null, 'B'));
            result = Math.max(result, dfs(tree[i], null, 'R'));

        }
        System.out.println(result);

    }

//    public static void dfs2(TreeNode tree, TreeNode parent){
//        if(tree==null) return;
        int result = 0;
//        for(int i=0;i<tree.friends.size();i++){
//            if(tree.friends.get(i)==parent) continue;
//            if(tree.colors.get(i)=='R')
//                result = Math.max(result,dfs(tree.friends.get(i),tree,'B')+1);
//            else
//                result = Math.max(result,dfs(tree.friends.get(i),tree,'R')+1);
//            dfs2(tree.friends.get(i),tree);
//        }
//    }

    public static int dfs(TreeNode tree, TreeNode parent, char color){
        if(tree==null) return 0;
        int res = 0;
        for(int i=0;i<tree.friends.size();i++){
            if(tree.friends.get(i)==parent) continue;
            if(tree.colors.get(i)==color) {
                if(color=='R')
                    res = Math.max(res,dfs(tree.friends.get(i),tree,'B')+1);
                else
                    res = Math.max(res,dfs(tree.friends.get(i),tree,'R')+1);
            }
        }
        return res;
    }

}

JS

const readline = require('readline');

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
});

const lines = [];

(async () => {
    for await (const line of rl) {
        lines.push(line);
    }
    const n = parseInt(lines[0]);
    const edges = [[]];
    // construct the graph
    for (let i = 1; i < lines.length; i++) {
        const [u, v, color] = lines[i].split(' ');
        if (!Array.isArray(edges[parseInt(u)])) {
            edges[parseInt(u)] = [];
        }
        edges[parseInt(u)].push([parseInt(v), color === 'R' ? 0 : 1]);
        if (!Array.isArray( edges[parseInt(v)])) {
            edges[parseInt(v)] = [];
        }
        edges[parseInt(v)].push([parseInt(u), color === 'R' ? 0 : 1]);
    }
    // process the problem
    const dp = new Array(n + 1).fill([]).map(i => [0, 0]);
    let res = -Infinity;
    // dfs
    const dfs = (node, father) => {
        // is leaf node
        if (edges[node].length === 1 && edges[node][0][0] === father) {
            return;
        }

        // traverse every child node
        for (let i = 0; i < edges[node].length; i++) {
            const cur = edges[node][i][0];
            const color = edges[node][i][1];
            if (cur === father) {
                continue;
            }
            dfs(cur, node);
            dp[node][color] = Math.max(dp[node][color], dp[cur][color ^ 1] + 1);
        }
        res = Math.max(res, dp[node][0] + dp[node][1]);
    }

    dfs(1, 0);

    console.log(res);
})();

python

from collections import defaultdict

MAXN = 200005
n = 0
edge = defaultdict(list)
dp = [[0] * 2 for _ in range(MAXN)]
maxn = 0


def dfs(u, fa):
    global maxn
    if len(edge[u]) == 1 and edge[u][0][0] == fa:
        return

    for now in edge[u]:
        v = now[0]
        if v == fa:
            continue
        dfs(v, u)
        col = now[1]
        dp[u][col] = max(dp[u][col], dp[v][col ^ 1] + 1)
        maxn = max(maxn, dp[u][0] + dp[u][1])


def main():
    global n
    n = int(input())
    for _ in range(n - 1):
        u, v, ch = input().split()
        u, v = int(u), int(v)
        edge[u].append((v, 1 if ch == 'R' else 0))
        edge[v].append((u, 1 if ch == 'R' else 0))

    dfs(1, 0)
    print(maxn)


if __name__ == "__main__":
    main()

题目内容均收集自互联网,如如若此项内容侵犯了原著者的合法权益,可联系我: (CSDN网站注册
用户名: 塔子哥学算法) 进行删除。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

塔子哥学算法

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值