第一行输入两个整数 n 和 root,n 表示二叉树的总节点个数,root 表示二叉树的根节点。
以下 n 行每行四个整数 fa,lch,rch,val,表示 fa 的左儿子为 lch,右儿子为 rch。val 表示 fa 节点的值(如果 lch 为 0 则表示 fa 没有左儿子,rch同理)
输出一个整数表示最长链的长度。
9 1 1 2 3 -3 2 4 5 3 4 0 0 1 5 8 9 0 8 0 0 1 9 0 0 6 3 6 7 -9 6 0 0 2 7 0 0 1 6
4
9 1 1 2 3 -3 2 4 5 3 4 0 0 1 5 8 9 0 8 0 0 1 9 0 0 6 3 6 7 -9 6 0 0 2 7 0 0 1 -9
1
#include <iostream> #include <unordered_map> using namespace std; typedef struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} TreeNode(int x, TreeNode* _left, TreeNode* _right) : val(x), left(_left), right(_right) {} ~TreeNode() {} } *BT; typedef int Id; typedef struct TreeNodeInfo { Id id; int val; Id l_child, r_child; } *INFO; BT CreateBT(INFO infos, Id root_id) { if (!root_id) return nullptr; BT t = new TreeNode(infos[root_id].val); t->left = CreateBT(infos, infos[root_id].l_child); t->right = CreateBT(infos, infos[root_id].r_child); return t; } void dfs(TreeNode* root, int depth, int sum, int target, unordered_map<int, int>& mp, int& ans) { if (!root) return; sum += root->val; if (mp.find(sum) == end(mp)) mp[sum] = depth; if (mp.find(sum - target) != end(mp)) ans = max(ans, depth - mp[sum - target]); dfs(root->left, depth + 1, sum, target, mp, ans); dfs(root->right, depth + 1, sum, target, mp, ans); // backtracking if (mp.find(sum) != end(mp) && mp[sum] == depth) mp.erase(sum); } int main(const int argc, const char** argv) { ios::sync_with_stdio(false); cin.tie(0); int n, root_id; cin >> n >> root_id; TreeNodeInfo infos[n + 1]; Id fa, l_ch, r_ch; int val; while (n--) { cin >> fa >> l_ch >> r_ch >> val; infos[fa].id = fa; infos[fa].val = val; infos[fa].l_child = l_ch; infos[fa].r_child = r_ch; } int target; cin >> target; BT t = CreateBT(infos, root_id); int ans = 0; unordered_map<int, int> mp{{0, 0}}; dfs(t, 1, 0, target, mp, ans); cout << ans; return 0; }
class Node { public int val; public Node right; public Node left; public Node (int val) { this.val = val; } public Node () { } } public class Main { public static void main (String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); Node head = constructTree(sc, n); int k = sc.nextInt(); int result = countLongest(head, k); System.out.println(result); } public static Node constructTree (Scanner sc, int n) { HashMap<Integer, Node> map = new HashMap<>(); int rootID = sc.nextInt(); Node root = new Node(); map.put(rootID, root); for (int i = 0; i < n; i++) { int nodeID = sc.nextInt(); int leftID = sc.nextInt(); int rightID = sc.nextInt(); int value = sc.nextInt(); if (map.containsKey(nodeID)) { Node tmpNode = map.get(nodeID); tmpNode.val = value; Node leftNode = leftID == 0 ? null : new Node(); Node rightNode = rightID == 0 ? null : new Node(); tmpNode.left = leftNode; tmpNode.right = rightNode; if (leftID != 0) map.put(leftID, leftNode); if (rightID != 0) map.put(rightID, rightNode); } } return root; } public static int countLongest (Node head, int k) { //key表示某个累加和,value表示这个累加和在路径中最早出现层数 HashMap<Integer, Integer> map = new HashMap<>(); //表示不用包括任何节点就可以得到累加和为0 map.put(0,0); return preOrder (head, k, map, 0, 1, 0); } public static int preOrder (Node head, int k, HashMap<Integer, Integer> map, int preSum, int level, int maxLen) { if (head == null) { return maxLen; } int curSum = preSum + head.val; if (!map.containsKey(curSum)) map.put(curSum, level); if (map.containsKey(curSum-k)) { maxLen = Math.max(maxLen, level - map.get(curSum-k)); } maxLen = preOrder(head.left, k, map, curSum, level + 1, maxLen); maxLen = preOrder(head.right, k, map, curSum, level + 1, maxLen); //跑到头来说明已经把一条能检测的路走到头了,此时该走另外一条路了,若不删除当前 //新加进map里去的curSum和level,万一下一条路径有某个curSum-k恰好等于当前curSum //会误以为他们在同一条路径上,造成结果有误 if (level == map.get(curSum)) map.remove(curSum); return maxLen; } }
import java.util.HashMap; import java.util.Map; import java.util.Scanner; public class Main { static int maxLen = 0; public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); TreeNode root = createTree(scanner, n); int sum = scanner.nextInt(); Map<Integer, Integer> map = new HashMap<>(); map.put(0, 0); maxLength(root,sum,map,0,1); System.out.print(maxLen); } private static void maxLength(TreeNode node, int sum, Map<Integer, Integer> map, int preSum, int level) { if(node==null) return; int currSum = preSum + node.value; if(!map.containsKey(currSum)) { map.put(currSum, level); } if(map.containsKey(currSum-sum)) { maxLen = Math.max(maxLen, level - map.get(currSum-sum)); } maxLength(node.left,sum,map,currSum,level+1); maxLength(node.right,sum,map,currSum,level+1); if(map.get(currSum) == level) { map.remove(currSum); } } public static TreeNode createTree(Scanner scanner,int n) { Map<Integer, TreeNode> map = new HashMap<Integer, TreeNode>(); int val = scanner.nextInt(); TreeNode root = new TreeNode(); map.put(val, root); for(int i=0;i<n;i++) { int father = scanner.nextInt(); TreeNode node = map.get(father); int leftId = scanner.nextInt(); if(leftId!=0) { TreeNode left = new TreeNode(); map.put(leftId,left ); node.left = left; } int rightId = scanner.nextInt(); if(rightId != 0) { TreeNode right = new TreeNode(); map.put(rightId, right); node.right = right; } int value = scanner.nextInt(); node.value = value; } return root; } } class TreeNode{ int value; TreeNode left; TreeNode right; public TreeNode(int value, TreeNode left, TreeNode right) { super(); this.value = value; this.left = left; this.right = right; } public TreeNode(int value) { super(); this.value = value; this.left = null; this.right = null; } public TreeNode() { } }
import java.util.HashMap; import java.util.Scanner; public class Main { static int max_length = 0; public static void main(String[] args) { Scanner in = new Scanner(System.in); String [] first = in.nextLine().split(" "); int n = Integer.parseInt(first[0]); int root = Integer.parseInt(first[1]); int [][] nodes = new int[n][4]; for(int i = 0;i < n;i ++){ String [] str = in.nextLine().split(" "); int row = Integer.parseInt(str[0]); for(int j = 0;j < 4;j++){ nodes[row-1][j] = Integer.parseInt(str[j]); //使用数组来存放节点,每行第一个数-1确定节点所在的行。该行第一个元素代表根节点,第二个元素是其左子树,第三个元素是右子树,第四个是val } } int target = Integer.parseInt(in.nextLine()); HashMap<Integer, Integer> map = new HashMap<>(); //key代表出现过的累加和,value代表这个累加和上次在哪一层出现的 map.put(0, 0); //一定要有,代表累加和为0的最早在0层就出现 maxLength(nodes, root, target, map, 0,1); System.out.println(max_length); } public static void maxLength(int[][] nodes, int root, int target, HashMap<Integer, Integer> map, int preSum, int level){ if(root == 0) return; int curSum = preSum + nodes[root-1][3]; //当之前还没有出现过累加和为curSum的时候,加入map if(!map.containsKey(curSum)){ map.put(curSum, level); } //比如说level为5时,curSum = 13,target = 5,那么就要看之前有没有和为8的出现 //发现了level为2时,累加和为8 //那么这里的max_length就可以试着更新为5-2 = 3. //之所以这么说,是因为有个关系一直存在,target = curSum - preSum.这是我们追求的 //我们往map里加的都是preSum,所以就找curSum - target,使得追求的东西被实现 if(map.containsKey(curSum - target)){ max_length = Math.max(max_length, level - map.get(curSum - target)); } //继续查找左右子树 maxLength(nodes, nodes[root-1][1], target, map, curSum, level+1); maxLength(nodes, nodes[root-1][2], target, map, curSum, level+1); //我们在map中存放的是上层所有的和,以及他们对应的level, // 而如果在map中发现了curSum,且它的level不是上层,而且是当前这一层,那么说明curSum这个累加和的记录是在遍历到cur的时候加上去的 //那么就需要将这个记录删除掉,免得后面使用它。因为它并不是代表的上层的多少个数的和值。 if(map.get(curSum) == level) map.remove(curSum); } }//class end
class TreeNode: def __init__(self, x): self.val = x self.left = 0 self.right = 0 class Solution: def __init__(self): self.mmax = 99999 self.v=[] self.mmaxdepth = 0 def dfs(self, root, depth, sum):#C++用引用传递,不知如何实现。 if root==0: return None sum = sum+self.v[root].val if sum==self.mmax and depth>self.mmaxdepth: self.mmaxdepth = depth self.dfs(self.v[root].left, depth+1, sum) self.dfs(self.v[root].right, depth+1, sum) def maxlen(self, root): if root==0: return 0 maxdepth = 0 self.dfs(root, 1,0) self.maxlen(self.v[root].left) self.maxlen(self.v[root].right) def ans(self): [n,root] = list(map(int,input().split())) self.v = [TreeNode(0) for i in range(n+1)] for i in range(n): [n1, l, r, val]=list(map(int,input().split())) self.v[n1].left=l self.v[n1].right=r self.v[n1].val = val self.mmax = int(input()) self.maxlen(root) print(self.mmaxdepth) if __name__=="__main__": Solution().ans()
let [n,root]=readline().split(' ').map(item=>parseInt(item)) let myMap=new Map() while(n--){ let [fa,lch,rch,val]=readline().split(' ').map(item=>parseInt(item)) myMap.set(fa,[lch,rch,val]) } let len=parseInt(readline()) const listNode=function(val){ this.val=val this.left=null this.right=null } const createTree=function(root){ if(root){ let [lch,rch,val]=myMap.get(root) let node=new listNode(val) node.left=createTree(lch) node.right=createTree(rch) return node } } const treeHead=createTree(root) let res=0 const getMaxLength=function(treeHead,n){ let sumMap=new Map() sumMap.set(0,0) preOrder(treeHead,n,0,1,sumMap) } const preOrder=function(root,target,presum,level,sumMap){ if(root==null) return ; let curSum=presum+root.val if(!sumMap.has(curSum)) sumMap.set(curSum,level) if(sumMap.has(curSum-target)) res=Math.max(level-sumMap.get(curSum-target),res) preOrder(root.left,target,curSum,level+1,sumMap) preOrder(root.right,target,curSum,level+1,sumMap) if(sumMap.get(curSum)==level) sumMap.delete(curSum) } getMaxLength(treeHead,len) console.log(res)
#include<cstdio> #include<vector> #include<algorithm> using namespace std; int n,root,mmax; struct node{ int data; int lchild,rchild; }; vector<node> v; void dfs(int root,int depth,int sum,int &mmaxdepth){ if(root==0) return; sum=sum+v[root].data; if(sum==mmax&&depth>mmaxdepth) { mmaxdepth=depth; } dfs(v[root].lchild,depth+1,sum,mmaxdepth); dfs(v[root].rchild,depth+1,sum,mmaxdepth); } int maxlen(int root){ if(root==0){ return 0; } int m0=0,ml=0,mr=0; dfs(root,1,0,m0); ml=maxlen(v[root].lchild); mr=maxlen(v[root].rchild); return max(m0,max(ml,mr)); } int main(){ int n1,l,r,val; scanf("%d %d",&n,&root); v.resize(n+1); for(int i=0;i<n;++i){ scanf("%d %d %d %d",&n1,&l,&r,&val); v[n1].data=val; v[n1].lchild=l; v[n1].rchild=r; } scanf("%d",&mmax); int sum=maxlen(root); printf("%d",sum); }
#include<bits/stdc++.h> using namespace std; // 双递归常规操作 // 此递归用于求解最长路径 void findLongestPath(int root,int* lc,int* rc,int* score,int rest,int cur_len,int& ans) { // 累加和为0 更新最长路径长度 if(rest==0) ans = max(ans,cur_len); // 到叶节点了 返回 if(!root) return; // 累加上当前结点的值,继续去左右子树搜索 findLongestPath(lc[root],lc,rc,score,rest-score[root],cur_len+1,ans); findLongestPath(rc[root],lc,rc,score,rest-score[root],cur_len+1,ans); } // 此递归用于遍历整棵树 // 因为最长路径可能以任意结点为起点 void visit(int root,int* lc,int* rc,int* score,int rest,int& ans) { if(!root) return; findLongestPath(root,lc,rc,score,rest,0,ans); visit(lc[root],lc,rc,score,rest,ans); visit(rc[root],lc,rc,score,rest,ans); } int main() { int n,root; cin>>n>>root; int* lc = new int[n+1]; int* rc = new int[n+1]; int* score = new int[n+1]; int p; for(int i=0;i<n;++i) { cin>>p; cin>>lc[p]>>rc[p]>>score[p]; } int target; cin>>target; int ans = 0; visit(root,lc,rc,score,target,ans); cout<<ans<<endl; return 0; }