Leetcode.2867 统计树中的合法路径数目

news/2024/12/2 13:44:58/

题目链接

Leetcode.2867 统计树中的合法路径数目 rating : 2428

题目描述

给你一棵 n n n 个节点的无向树,节点编号为 1 1 1 n n n 。给你一个整数 n n n 和一个长度为 n − 1 n - 1 n1 的二维整数数组 e d g e s edges edges ,其中 e d g e s [ i ] = [ u i , v i ] edges[i] = [u_i, v_i] edges[i]=[ui,vi] 表示节点 u i u_i ui v i v_i vi 在树中有一条边。

请你返回树中的 合法路径数目

如果在节点 a a a 到节点 b b b 之间 恰好有一个 节点的编号是质数,那么我们称路径 ( a , b ) (a, b) (a,b)合法的

注意:

  • 路径 ( a , b ) (a, b) (a,b) 指的是一条从节点 a a a 开始到节点 b b b 结束的一个节点序列,序列中的节点 互不相同 ,且相邻节点之间在树上有一条边。
  • 路径 ( a , b ) (a, b) (a,b) 和路径 ( b , a ) (b, a) (b,a) 视为 同一条 路径,且只计入答案 一次
示例 1:

在这里插入图片描述

输入:n = 5, edges = [[1,2],[1,3],[2,4],[2,5]]
输出:4
解释:恰好有一个质数编号的节点路径有:

  • (1, 2) 因为路径 1 到 2 只包含一个质数 2 。
  • (1, 3) 因为路径 1 到 3 只包含一个质数 3 。
  • (1, 4) 因为路径 1 到 4 只包含一个质数 2 。
  • (2, 4) 因为路径 2 到 4 只包含一个质数 2 。
    只有 4 条合法路径。
示例 2:

在这里插入图片描述

输入:n = 6, edges = [[1,2],[1,3],[2,4],[3,5],[3,6]]
输出:6
解释:恰好有一个质数编号的节点路径有:

  • (1, 2) 因为路径 1 到 2 只包含一个质数 2 。
  • (1, 3) 因为路径 1 到 3 只包含一个质数 3 。
  • (1, 4) 因为路径 1 到 4 只包含一个质数 2 。
  • (1, 6) 因为路径 1 到 6 只包含一个质数 3 。
  • (2, 4) 因为路径 2 到 4 只包含一个质数 2 。
  • (3, 6) 因为路径 3 到 6 只包含一个质数 3 。
    只有 6 条合法路径。
提示:
  • 1 ≤ n ≤ 1 0 5 1 \leq n \leq 10^5 1n105
  • e d g e s . l e n g t h = n − 1 edges.length = n - 1 edges.length=n1
  • e d g e s [ i ] . l e n g t h = 2 edges[i].length =2 edges[i].length=2
  • 1 ≤ u i , v i ≤ n 1 \leq u_i, v_i \leq n 1ui,vin
  • 输入保证 e d g e s edges edges 形成一棵合法的树。

解法:筛质数 + dfs

我们先将 [ 1 , 1 0 5 ] [1,10^5] [1,105] 内的质数筛出来,用 n p np np 记录。如果 n p [ x ] = t r u e np[x] = true np[x]=true,说明 x x x 不是质数;否则是质数。

我们可以从 质数点 x x x 出发,开始 dfs,访问非质数点,因为一条 合法路径 只存在一个质数点。

通过上述操作,可以将 x x x 连接的几个 非质数连通块 计算出来。

在这里插入图片描述

假设如上图,通过 x x x 分割出了三个 非质数连通块 ,每个连通块中的节点数量分别为 2 , 3 , 4 2,3,4 2,3,4

我们现在来计算 合法路径数量从左到右计算,保证不重不漏):

  • 1 1 1号连通块 通过 x x x 2 2 2号联通块 组成的路径数为 2 × 3 = 6 2\times 3 = 6 2×3=6
  • 1 1 1号连通块, 2 2 2号连通块 通过 x x x 3 3 3号连通块 组成的路径数为 ( 2 + 3 ) × 4 = 20 (2 + 3) \times 4 = 20 (2+3)×4=20
  • 以及所有连通块的节点数量 9 9 9

上图通过 x x x 的合法路径条数为 6 + 20 + 9 = 35 6 + 20 + 9 = 35 6+20+9=35

我们可以用一个数组 s z sz sz,记录下已经计算过的连通块数量。假设 1 1 1 号连通块中的两个节点分别为 i , j i , j i,j,那么 s z [ i ] = s z [ j ] = 2 sz[i] = sz[j] = 2 sz[i]=sz[j]=2

如果下一次有另外一个 质数点 y y y 和这个 1 1 1号连通块 相连,那么我们就可以直接计算,不用再次遍历记录连通块节点的数量。

时间复杂度: O ( n ) O(n) O(n)

C++代码:

using LL = long long;const int MX = 1e5;
bool np[MX + 1];auto init = []() ->int{np[1] = true;for(int i = 2;i * i <= MX;i++){if(!np[i]){for(int j = i * i;j <= MX;j += i) np[j] = true;}}return 0;
}();class Solution {
public:long long countPaths(int n, vector<vector<int>>& edges) {vector<vector<int>> g(n + 1);for(auto &e:edges){auto a = e[0] , b = e[1];g[a].push_back(b);g[b].push_back(a);}vector<int> sz(n + 1);vector<int> nodes;function<void(int,int)> dfs = [&](int x,int fa) ->void{nodes.push_back(x);for(auto y:g[x]){if(y == fa || !np[y]) continue;dfs(y,x);}};LL ans = 0;for(int x = 1;x <= n;x++){if(np[x]) continue; //合数就跳过 , 是以质数为起点dfsLL sum = 0;for(auto y : g[x]){//接着要求的是合数的连通块if(!np[y]) continue;//如果这个连通块没有被计算过,就计算if(sz[y] == 0){nodes.clear();dfs(y,-1);for(auto node:nodes) sz[node] = nodes.size();}ans += sum * sz[y];sum += sz[y];}ans += sum;}return ans;}
};

http://www.ppmy.cn/news/1149928.html

相关文章

同创永益成为英迈首家签约生态伙伴

日前&#xff0c;同创永益已和英迈签署生态运营战略协议&#xff0c;并正式成为英迈全新打造的GTM生态圈的首位签约合作伙伴。双方将携手对“同创数字韧性平台”产品进行一站式联合解决方案的持续整合&#xff0c;并将大力推动该联合解决方案在市场上的进一步拓展。 云原生时代…

在服务器上解压.7z文件

1. 更新apt sudo apt-get update2. 安装p7zip sudo apt-get install p7zip-full3. 解压.7z文件 7za x WN18RR.7z

免费使用Salesforce Data Cloud!详细操作步骤来啦

Data Cloud是Salesforce向市场推出的增长最快的产品&#xff0c;这对Salesforce来说是一个重要竞争优势。 近期&#xff0c;Salesforce宣布客户可以免费使用Data Cloud。这就是所谓的零美元SKU&#xff0c;换句话说&#xff0c;这是一条不会产生任何成本的Salesforce产品线。 …

AI人工智能入门之图像识别

人工智能&#xff08;Artificial Intelligence&#xff0c;简称AI&#xff09;是一门涵盖多个领域的科学技术&#xff0c;旨在使计算机能够模拟人类智能。 其中一个热门的应用领域就是图像识别。 图像识别是指计算机通过对一幅图像进行分析和处理&#xff0c;来识别和理解图像…

springboot中自定义过滤器用Component注解不用Configuration注解的坏处是什么

在Spring Boot中&#xff0c;如果你使用Component注解来标记自定义过滤器类而不使用Configuration注解&#xff0c;可能会有以下一些潜在的问题和限制&#xff1a; 过滤器顺序问题&#xff1a;使用Component注解标记的类是被自动扫描并创建为Bean的&#xff0c;它们的注册顺序…

Redis哨兵机制原理

Redis哨兵机制可以保证Redis服务的高可用性。它通过启动一个或多个哨兵进程&#xff0c;监控Redis主服务器是否宕机&#xff0c;如果宕机&#xff0c;哨兵进程会自动将一个从服务器&#xff08;Slave&#xff09;升级为主服务器&#xff08;Master&#xff09;&#xff0c;并通…

jmeter压测记录、使用方法

jmeter压测记录、使用方法 1、非gui方式执行压测命令2、压测命令输出解读 1、非gui方式执行压测命令 sh jmeter.sh -n -t test.jmx -l result.jtl2、压测命令输出解读 Active: 10 Started: 10 Finished: 0 Active: 10 正在进行的压测线程数&#xff1a;总的减去已完成的压测…

【DevOps】DevOps—基本概念

文章目录 1. DevOps2. CI/CD 1. DevOps 维基百科定义&#xff1a; DevOps是一组过程、方法与系统的统称&#xff0c;用于促进 开发、技术运营 和 质量保障&#xff08;QA&#xff09; 部门之间的沟通、协作与整合。我理解DevOps是一种软件管理思维模式。 为什么会有DevOps呢&…