Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

การลบขอบสูงสุดจากทรีเพื่อสร้างฟอเรสต์ใน C++


คำชี้แจงปัญหา

จากต้นไม้ที่ไม่มีทิศทางซึ่งมีจุดยอดเป็นคู่ เราจำเป็นต้องลบจำนวนขอบสูงสุดออกจากต้นไม้นี้ เพื่อให้องค์ประกอบที่เชื่อมต่อกันของฟอเรสต์ผลลัพธ์มีจำนวนจุดยอดเท่ากัน

ตัวอย่าง

การลบขอบสูงสุดจากทรีเพื่อสร้างฟอเรสต์ใน C++

ในแผนภูมิต้นไม้ที่แสดงด้านบนนี้ เราสามารถลบได้สูงสุด 2 ขอบ 0-2 และ 0-4 ที่แสดงเป็นสีแดง เพื่อให้ส่วนประกอบที่เชื่อมต่อแต่ละรายการมีจำนวนจุดยอดเท่ากัน

อัลกอริทึม

  • ทำ DFS จากโหนดเริ่มต้นใดๆ เมื่อเชื่อมต่อต้นไม้
  • เริ่มต้นการนับโหนดในทรีย่อยที่รูทภายใต้โหนดปัจจุบันเป็น 0
  • ทำตามแบบเรียกซ้ำสำหรับทุกทรีย่อยของโหนดปัจจุบัน −
    • ถ้าขนาดของทรีย่อยปัจจุบันเท่ากัน ให้เพิ่มผลลัพธ์ 1 เนื่องจากเราสามารถยกเลิกการเชื่อมต่อทรีย่อยได้
    • เพิ่มจำนวนโหนดในทรีย่อยปัจจุบันไปยังจำนวนปัจจุบัน

ตัวอย่าง

เรามาดูตัวอย่างกัน −

#include <bits/stdc++.h>
using namespace std;
int dfs(vector<int> g[], int u, bool visit[], int& res) {
   visit[u] = true;
   int currComponentNode = 0;
   for (int i = 0; i < g[u].size(); i++) {
      int v = g[u][i];
      if (!visit[v]) {
         int subtreeNodeCount = dfs(g, v, visit, res);
         if (subtreeNodeCount % 2 == 0)
            res++;
         else
            currComponentNode += subtreeNodeCount;
      }
   }
   return (currComponentNode + 1);
}
int maxEdgeRemovalToMakeForestEven(vector<int> g[], int N) {
   bool visit[N + 1];
   for (int i = 0; i <= N; i++)
   visit[i] = false;
   int res = 0;
   dfs(g, 0, visit, res);
   return res;
}
void addEdge(vector<int> g[], int u, int v) {
   g[u].push_back(v);
   g[v].push_back(u);
}
int main() {
   int edges[][2] = {{0, 2}, {0, 1}, {0, 4}, {2, 3}, {4, 5}, {5, 6}, {5, 7} };
   int N = sizeof(edges)/sizeof(edges[0]); vector<int> g[N + 1];
   for (int i = 0; i < N; i++)
   addEdge(g, edges[i][0], edges[i][1]);
   cout << "Answer = " << maxEdgeRemovalToMakeForestEven(g, N) << endl;
   return 0;
}

ผลลัพธ์

Answer = 2