Skip to content
TheCScience
TheCScience
  • Pages
    • About US
    • Contact US
    • Privacy Policy
    • DMCA
  • Human values
  • NCERT Solutions
  • HackerRank solutions
    • HackerRank Algorithms Problems Solutions
    • HackerRank C solutions
    • HackerRank C++ problems solutions
    • HackerRank Java problems solutions
    • HackerRank Python problems solutions
TheCScience
TheCScience

HackerRank Cut Tree Problem Solution

Yashwant Parihar, July 2, 2023August 1, 2024

In this post, we will solve HackerRank Cut Tree Problem Solution.

Given a tree T with n nodes, how many subtrees (T’) of T have at most K edges connected to (T – T’)?

Input Format

The first line contains two integers n and K followed by n-1 lines each containing two integers a & b denoting that there’s an edge between a & b.

Constraints

1 <= K <= n <= 50
Every node is indicated by a distinct number from 1 to n.

Output Format

A single integer which denotes the number of possible subtrees.

Sample Input

3 1
2 1
2 3

Sample Output

6

Explanation

There are 2^3 possible sub-trees:

{} {1} {2} {3} {1, 2} {1, 3} {2, 3} {1, 2, 3}

But:
the sub-trees {2} and {1,3} are not valid. {2} isn’t valid because it has 2 edges connecting to it’s complement {1,3} whereas K = 1 in the sample test-case {1,3} isn’t valid because, well, it’s not a sub-tree. The nodes aren’t connected.

HackerRank Cut Tree Problem Solution
HackerRank Cut Tree Problem Solution

Cut Tree C Solution

#include <stdio.h>
#include <stdlib.h>
void dfs(int x,int parent);
int table[50][50]={0},c[50]={0},p[50],q[51]={0},N;
long long dp1[50][51]={0},dp2[50][51]={0},temp[51],ans; // 1 without 2 with [node][K]
int main(){
  int K,x,y,i,j,k;
  scanf("%d%d",&N,&K);
  for(i=0;i<N-1;i++){
    scanf("%d%d",&x,&y);
    table[x-1][y-1]=-1;
    table[y-1][x-1]=-1;
  }
  dfs(0,0);
  for(i=0;i<N;i++)
    if(!c[i])
      q[++q[0]]=i;
  while(q[0]){
    x=q[q[0]--];
    dp1[x][0]=dp2[x][0]=1;
    for(i=0;i<N;i++)
      if(table[x][i]==1){
        for(j=1;j<=K;j++)
          temp[j]=0;
        for(j=1;j<=K;j++){
          dp1[x][j]+=dp1[i][j]+dp2[i][j-1];
          for(k=0;k<=j;k++)
            if(k==1)
              temp[j]+=(dp2[i][k]+1)*dp2[x][j-k];
            else
              temp[j]+=dp2[i][k]*dp2[x][j-k];
        }
        for(j=1;j<=K;j++)
          dp2[x][j]=temp[j];
      }
    if(x){
      c[p[x]]--;
      if(!c[p[x]])
        q[++q[0]]=p[x];
    }
  }
  for(i=0,ans=0;i<=K;i++)
    ans+=dp1[0][i]+dp2[0][i];
  printf("%lld",ans);
  return 0;
}
void dfs(int x,int parent){
  int i;
  p[x]=parent;
  for(i=0;i<N;i++)
    if(table[x][i] && i!=parent){
      table[x][i]+=2;
      c[x]++;
      dfs(i,x);
    }
  return;
}

Cut Tree C++ Solution

#include <bits/stdc++.h>

using namespace std;

vector<string> split_string(string);

/*
 * Complete the cuttree function below.
 */
pair<vector<long>, vector<long> > br(const vector<vector<int> >& g, int i, int i0)
{
    vector<long> w(1, 1), wo;
    for (auto j: g[i]) if (j != i0)
    {
        auto [wp, wop] = br(g, j, i);
        if (wop.size() > wo.size()) wo.resize(wop.size(), 0);
        for (int i = 0; i < wop.size(); ++i) wo[i] += wop[i];
        if (wp.size() + 1 > wo.size()) wo.resize(wp.size() + 1, 0);
        for (int i = 0; i < wp.size(); ++i) wo[i+1] += wp[i];
        vector<long> w2(max(1+int(w.size()), int(wp.size() + w.size()) - 1), 0);
        for (int i = 0; i < w.size(); ++i)
        {
            w2[i+1] += w[i];
            for (int k = 0; k < wp.size(); ++k) w2[i+k] += w[i]*wp[k];
        }
        swap(w, w2);
    }
    return {w, wo};
}

long cutTree(int n, int k, vector<vector<int>> edges) {
    /*
     * Write your code here.
     */
    vector<vector<int> > g(n);
    for (auto& v: edges)
    {
        --v[0]; --v[1];
        g[v[0]].push_back(v[1]);
        g[v[1]].push_back(v[0]);
    }
    auto [w, wo] = br(g, 0, -1);
    for (auto k: w) cout << k << " "; cout << "\n";
    for (auto k: wo) cout << k << " "; cout << "\n";
    long res = 0;
    for (int i = 0; i < min<int>(w.size(), k+1); ++i) res += w[i];
    for (int i = 0; i < min<int>(wo.size(), k+1); ++i) res += wo[i];
    return res+1;
}

int main()
{
    ofstream fout(getenv("OUTPUT_PATH"));

    string nk_temp;
    getline(cin, nk_temp);

    vector<string> nk = split_string(nk_temp);

    int n = stoi(nk[0]);

    int k = stoi(nk[1]);

    vector<vector<int>> edges(n-1);
    for (int edges_row_itr = 0; edges_row_itr < n-1; edges_row_itr++) {
        edges[edges_row_itr].resize(2);

        for (int edges_column_itr = 0; edges_column_itr < 2; edges_column_itr++) {
            cin >> edges[edges_row_itr][edges_column_itr];
        }

        cin.ignore(numeric_limits<streamsize>::max(), '\n');
    }

    long result = cutTree(n, k, edges);

    fout << result << "\n";

    fout.close();

    return 0;
}

vector<string> split_string(string input_string) {
    string::iterator new_end = unique(input_string.begin(), input_string.end(), [] (const char &x, const char &y) {
        return x == y and x == ' ';
    });

    input_string.erase(new_end, input_string.end());

    while (input_string[input_string.length() - 1] == ' ') {
        input_string.pop_back();
    }

    vector<string> splits;
    char delimiter = ' ';

    size_t i = 0;
    size_t pos = input_string.find(delimiter);

    while (pos != string::npos) {
        splits.push_back(input_string.substr(i, pos - i));

        i = pos + 1;
        pos = input_string.find(delimiter, i);
    }

    splits.push_back(input_string.substr(i, min(pos, input_string.length()) - i + 1));

    return splits;
}

Cut Tree C Sharp Solution

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

class Solution {
    private class Node {
        public int Id { get; set; }
        public List<Node> Children { get; set; }
    }

    /*
     * Complete the cuttree function below.
     */
    static long cutTree(int n, int k, int[][] edges) {
        var dp = new long[n, k + 1];
        var graph = new List<int>[n];
        
        for (var i = 0; i < n; ++i) {
            graph[i] = new();
        }
        
        foreach (var edge in edges) {
            var u = edge[0] - 1;
            var v = edge[1] - 1;
            graph[u].Add(v);
            graph[v].Add(u);
        }

        var rootNode = new Node {
            Id = 0,
            Children = new()
        };
        
        BuildTree(graph, rootNode, -1);
        
        return Solve(rootNode, dp, k) + 1;
    }
    
    private static void BuildTree(List<int>[] graph, Node curNode, int parentNodeId) {
        foreach (var childNodeId in graph[curNode.Id].Where(n => n != parentNodeId)) {
            var childNode = new Node {
                Id = childNodeId,
                Children = new()
            };
            curNode.Children.Add(childNode);
            BuildTree(graph, childNode, curNode.Id);
        }
    }
    
    private static long Solve(Node node, long[,] dp, int k) {
        if (node.Children.Count == 0) {
            dp[node.Id, 0] = 1;
            return 1;
        }
        
        var ans = 0L;
        
        foreach (var childNode in node.Children) {
            ans += Solve(childNode, dp, k);
        }
        
        var dp2 = new long[k + 1, node.Children.Count];
        
        for (var i = 0; i <= k; ++i) {
            dp2[i, 0] = dp[node.Children[0].Id, i];
            
            if (i == 1) {
                ++dp2[i, 0];
            }
            
            for (var j = 1; j < node.Children.Count; ++j) {
                for (var k2 = 0; k2 <= i; ++k2) {
                    var extra = i - k2 == 1 ? 1 : 0;
                    dp2[i, j] += dp2[k2, j - 1] * (dp[node.Children[j].Id, i - k2] + extra);
                }
            }
            
            dp[node.Id, i] = dp2[i, node.Children.Count - 1];
            
            if (i < k || node.Id == 0) {
                ans += dp[node.Id, i];
            }
        }
        
        return ans;
    }

    static void Main(string[] args) {
        TextWriter textWriter = new StreamWriter(@System.Environment.GetEnvironmentVariable("OUTPUT_PATH"), true);

        string[] nk = Console.ReadLine().Split(' ');

        int n = Convert.ToInt32(nk[0]);

        int k = Convert.ToInt32(nk[1]);

        int[][] edges = new int[n-1][];

        for (int edgesRowItr = 0; edgesRowItr < n-1; edgesRowItr++) {
            edges[edgesRowItr] = Array.ConvertAll(Console.ReadLine().Split(' '), edgesTemp => Convert.ToInt32(edgesTemp));
        }

        var result = 0L;

        checked {
            result = cutTree(n, k, edges);
        }
        
        textWriter.WriteLine(result);

        textWriter.Flush();
        textWriter.Close();
    }
}

Cut Tree Java Solution

import java.io.*;
import java.util.*;

public class cuttree extends PrintWriter {
    cuttree() { super(System.out, true); }
    Scanner sc = new Scanner(System.in);
    public static void main(String[] $) {
        cuttree o = new cuttree(); o.main(); o.flush();
    }

    int[] eo; int[][] ej;
    void append(int i, int j) {
        int o = eo[i]++;
        if (o >= 2 && (o & o - 1) == 0)
            ej[i] = Arrays.copyOf(ej[i], o << 1);
        ej[i][o] = j;
    }
    long[][] dp; long[] tt; int k;
    void init(int n) {
        eo = new int[n]; ej = new int[n][2];
        dp = new long[n][k + 1]; tt = new long[k + 1];
    }
    void mult(long[] aa, long[] bb) {
        Arrays.fill(tt, 0);
        for (int i = 0; i <= k; i++)
            for (int j = 0; i + j <= k; j++)
                tt[i + j] += aa[i] * bb[j];
        System.arraycopy(tt, 0, aa, 0, k + 1);
    }
    long ans = 1;
    void dfs(int p, int i) {
        dp[i][0] = 1;
        for (int o = eo[i]; o-- > 0; ) {
            int j = ej[i][o];
            if (j != p) {
                dfs(i, j);
                dp[j][1]++;
                mult(dp[i], dp[j]);
            }
        }
        for (int h = p == -1 ? k : k - 1; h >= 0; h--)
            ans += dp[i][h];
    }
    void main() {
        int n = sc.nextInt();
        if (n == 1) {
            println(2);
            return;
        }
        k = sc.nextInt();
        if (k == n)
            k = n - 1;
        init(n);
        for (int h = 0; h < n - 1; h++) {
            int i = sc.nextInt() - 1;
            int j = sc.nextInt() - 1;
            append(i, j);
            append(j, i);
        }
        dfs(-1, 0);
        println(ans);
    }
}

Cut Tree Python Solution

line = input().split()
n = int(line[0])
K = int(line[1])

adjlst = [[1]]
for i in range(n):
    adjlst.append([])
adjlst[1].append(0)

for i in range(n - 1):
    line = input().split()
    x = int(line[0])
    y = int(line[1])
    adjlst[x].append(y)
    adjlst[y].append(x)

def dfs(node, par, adjlst, K):
    conlst = [0] * (K + 1)
    dislst = [0] * (K + 1)
    conlst[0] = 1
    for chld in adjlst[node]:
        if chld != par:
            tcl, tdl = dfs(chld, node, adjlst, K)
            # print(str(tcl))
            # print(str(tdl))
            dislst[0] += tdl[0]
            tcl2 = [0] * (K + 1)
            for i in range(K):
                dislst[i + 1] += tcl[i] + tdl[i + 1]
                tcl2[i + 1] += conlst[i]
            for i in range(K + 1):
                for j in range(K + 1):
                    if i + j <= K:
                        tcl2[i + j] += tcl[i] * conlst[j]
            conlst = list(tcl2)
    return conlst, dislst

conlst, dislst = dfs(1, 0, adjlst, K)
# print(str(conlst))
# print(str(dislst))
ans = sum(conlst) + sum(dislst) + 1
print(str(ans))
c C# C++ HackerRank Solutions java python CcppCSharpHackerrank Solutionsjavapython

Post navigation

Previous post
Next post

Similar websites

  • Programming
  • Data Structures
©2025 TheCScience | WordPress Theme by SuperbThemes