C++, JAVA, PYTHON &  explanation
Let \n\nf1(node) be the value of maximum money we can rob from the subtree with node as root ( we can rob node if necessary).\n\nf2(node) be the value of maximu
Let \n\n`f1(node)` be the value of maximum money we can rob from the subtree with `node` as root ( we can rob `node` if necessary).\n\n`f2(node)` be the value of maximum money we can rob from the subtree with `node` as root but without robbing `node`. \n\nThen we have \n\n`f2(node) = f1(node.left) + f1(node.right)` and \n\n`f1(node) = max(  f2(node.left)+f2(node.right)+node.value,  f2(node) )`.\n\n# C++\n\n    class Solution {\n    public:\n        int rob(TreeNode* root) {\n            return robDFS(root).second;\n        }\n        pair<int, int> robDFS(TreeNode* node){\n            if( !node) return make_pair(0,0);\n            auto l = robDFS(node->left);\n            auto r = robDFS(node->right);\n            int f2 = l.second + r.second;\n            int f1 = max(f2, l.first + r.first + node->val);\n            return make_pair(f2, f1);\n        }\n    };\n\n\n# JAVA\n\n    public class Solution {\n        public int rob(TreeNode root) {\n            return robDFS(root)[1];\n        }\n        int[] robDFS(TreeNode node){\n            int [] res = new int[2];\n            if(node==null) return res;\n            int [] l = robDFS(node.left);\n            int [] r = robDFS(node.right);\n            res[0] = l[1] + r[1];\n            res[1] = Math.max(res[0], l[0] + r[0] + node.val);\n            return res;\n        }\n    }\n\n# PYTHON\n\n    class Solution(object):\n        def rob(self, root):\n            return self.robDFS(root)[1];\n        def robDFS(self,node):\n            if node is None:\n                return (0,0)\n            l = self.robDFS(node.left)\n            r = self.robDFS(node.right)\n            return (l[1] + r[1], max(l[1] + r[1], l[0] + r[0] + node.val))
[]