কম্পিউটার টিউটোরিয়াল

C++ দিয়ে ট্রি-এ সাবট্রির DFS কোয়ারী সমাধান

এই সমস্যায় আমাদের একটি বাইনারি ট্রি দেওয়া আছে এবং একটি নির্দিষ্ট নোড থেকে DFS (Depth First Search) করতে হবে যেখানে সেই নোডকে রুট ধরে DFS করা হবে।

C++ দিয়ে ট্রি-এ সাবট্রির DFS কোয়ারী সমাধান

উপরের ট্রিতে ধরি আমাদের নোড F-থেকে DFS করতে হচ্ছে।

এই টিউটোরিয়ালে আমরা কিছু অনন্য পদ্ধতি প্রয়োগ করব যাতে টাইম কমপ্লেক্সিটি উল্লেখযোগ্যভাবে কমে যায় এবং উচ্চ কনস্ট্রেইন্টের জন্যও কোডটি চলে।

পদ্ধতি − এই পদ্ধতিতে আমরা নїв (naive) পথে যাবো না অর্থাৎ প্রতিটি নোডের জন্য আলাদা DFS করবো না কারণ এটি উচ্চ কনস্ট্রেইন্টের জন্য কাজ করবে না (TLE দেবে)। তাই আমরা কিছু অনন্য পদ্ধতি ব্যবহার করব TLE এড়ানোর জন্য।

 #include <bits/stdc++.h> using namespace std; #define N 100000 // অ্যাডজেসেন্সি লিস্ট vector<int> v[N]; unordered_map<int, int> mape; // নোডকে তার ইনডেক্সের সাথে ম্যাপ করার জন্য vector<int> a; void dfs(int nodesunder[], int child, int parent){ // DFS ও nodesunder প্রিক্যালকুলেশন     a.push_back(child); // ট্রির DFS অর্ডার সংরক্ষণ     nodesunder[child] = 1;     for (auto it : v[child]) { // সাধারণ DFS         if (it != parent) { // সাইকেল এড়ানোর জন্য প্যারেন্ট এড়ানো             dfs(nodesunder, it, child); // রিকার্সিভ কল             nodesunder[child] += nodesunder[it]; // চাইল্ডের নিচের নোড যোগ করা         }     } } // সাবট্রির DFS প্রিন্ট করার ফাংশন void printDFS(int node, int nodesunder[]){     int ind = mape[node]; // DFS অ্যারেতে নোডের ইনডেক্স     cout << "The DFS of subtree " << node << ": ";     // সাবট্রির DFS প্রিন্ট     for (int i = ind; i < ind + nodesunder[node]; i++){ // DFS অ্যারেতে নোডের ইনডেক্স থেকে তার সাবট্রির সব নোড প্রিন্ট         cout << a[i] << " ";     }     cout << endl; } void addEdgetoGraph(int x, int y){ // অ্যাডজেসেন্সি লিস্ট মেইনটেইন     v[x].push_back(y);     v[y].push_back(x); } void mark(){ // প্রতিটি নোডকে DFS অ্যারেতে তার ইনডেক্স দিয়ে মার্ক করা     int size = a.size();     for (int i = 0; i < size; i++) {         mape[a[i]] = i;     } } int main(){     int n = 7;     // ট্রির এজ যোগ করা     addEdgetoGraph(1, 2);     addEdgetoGraph(1, 3);     addEdgetoGraph(2, 4);     addEdgetoGraph(2, 5);     addEdgetoGraph(4, 6);     addEdgetoGraph(4, 7);     // প্রতিটি নোডের সাবট্রিতে নোড সংখ্যা রাখার অ্যারে     int nodesunder[n + 1];     dfs(nodesunder, 1, 0); // nodesunder অ্যারে জেনারেট     mark(); // ম্যাপে ইনডেক্স মার্ক করা     // কোয়ারী ১     printDFS(2, nodesunder);     // কোয়ারী ২     printDFS(4, nodesunder);     return 0; }
আউটপুট
The DFS of subtree 2: 2 4 6 7 5 The DFS of subtree 4: 4 6 7
কোড বোঝা

এই পদ্ধতিতে আমরা DFS-এর অর্ডারটি প্রিক্যালকুলেট করে একটি ভেক্টরে রাখি। DFS প্রিক্যালকুলেট হলে, আমরা প্রতিটি নোড থেকে শুরু হয়ে তার সাবট্রিতে কতগুলো নোড আছে সেটাও বের করি। তারপর কোয়ারী করার সময় শুধু ওই নোডের স্টার্টিং ইনডেক্স থেকে তার সাবট্রির নোড সংখ্যা পর্যন্ত DFS অ্যারেটি ট্রাভার্স করি।

উপসংহার

এই টিউটোরিয়ালে আমরা ট্রির একটি সাবট্রির DFS কোয়ারী সমাধান করেছি। আমরা এই সমস্যার C++ প্রোগ্রাম ও সম্পূর্ণ পদ্ধতি দেখেছি। একই প্রোগ্রাম C, Java, Python ইত্যাদি ভাষায়ও লিখা যায়। আশা করি আপনি এই আর্টিকেলটি সহায়ক পাবেন।

  1. সি++-এ ট্রিতে পূর্বপুরুষ-বংশজ সম্পর্কের কোয়েরি সমাধান

  2. C++-এ ইনভার্টেড সাবট্রি (Inverted Subtree) চেক করার প্রোগ্রাম

  3. C++-এ বাইনারি ট্রি প্রিন্ট করা

  4. C++-এ একটি বাইনারি ট্রি অন্য বাইনারি ট্রির সাবট্রি কিনা তা যাচাই করা