从树中移除顶点后计算连通分量的查询


可以使用以下查询来确定删除树顶点后剩余的连通分量的数量:首先考虑树结构。然后,通过使用广度优先或深度优先搜索算法遍历树,检查每个连通分量。在删除所需顶点后,使用相同的遍历方法确定连通分量的数量。结果将由删除前后的计数差异决定。此方法有效地监视连接变化并帮助计算更新后的树中的连通分量。

使用的方法

  • 深度优先搜索 (DFS) 方法

  • 并查集方法

深度优先搜索 (DFS) 方法

在 DFS 方法中,我们首先从原始树中的任何选定节点执行 DFS 遍历,以计算删除树中的顶点后连通分量的数量。在此遍历期间,我们遍历每个连接的节点,将每个节点标记为已访问,并跟踪 DFS 的调用次数。在删除指定顶点后,我们执行新的 DFS 遍历,确保在探索阶段跳过已删除的顶点。通过比较删除前后 DFS 调用的次数,我们可以确定更新后的树中连通分量的数量。此方法有效地计算连通元素,同时调整树结构的变化。

算法

  • 在原始树上选择任何顶点作为 DFS 遍历的起点。

  • 设置变量“count”以开始计数连通分量。最初将其设置为 0。

  • 从选定的起始顶点开始,使用 DFS 遍历树。

  • 标记在 DFS 遍历期间访问的每个顶点,并为每个新的 DFS 调用(即,为找到的每个连通分量)将“count”增加 1。

  • DFS 遍历完成后,“count”将表示原始树中连通元素的数量。

  • 从树中删除指定的顶点。

  • 从相同的起始顶点重复 DFS 遍历,确保避免探索已删除的顶点。

  • 在运行 DFS 时,类似于之前更新“count”变量。

  • 升级后的树中关联组件的数量将由从初始“count”中减去撤离后的“count”决定。

示例

#include <iostream>
#include <vector>

void dfs(const std::vector<std::vector<int>>& tree, int v, 
std::vector<bool>& visited, int& count) {
   visited[v] = true;
   count++;
   for (int u : tree[v]) {
      if (!visited[u]) {
         dfs(tree, u, visited, count);
      }
   }
}

int countConnectedComponents(const std::vector<std::vector<int>>& tree, int startVertex) {
   int n = tree.size();
   std::vector<bool> visited(n, false);
   int count = 0;

   dfs(tree, startVertex, visited, count);
   return count;
}

int main() {
   std::vector<std::vector<int>> tree = {
      {1, 2},
      {0, 3},
      {0, 4},
      {1},
      {2}
   };

   int startVertex = 0;
   std::cout << countConnectedComponents(tree, startVertex) << std::endl;
   return 0;
}

输出

5

并查集方法

在并查集方法中,我们首先将每个顶点初始化为树中的一个单独的组件,以计算删除树中的顶点后连通分量的数量。为了跟踪原始树中的组件和连接,我们使用并查集数据结构。在删除指定顶点后,我们更新并查集数据结构以反映树的连通性的变化。然后计算并查集数据结构中不同集合的数量。结果计数表示树更新后的组件的连通性。删除顶点后,并查集方法有效地计算连通分量,并有效地处理树的结构变化。

算法

  • 从头开始创建一个数组或数据结构来表示每个顶点作为树的不同部分。最初,每个顶点都是它自己的父节点。

  • 在预处理步骤中使用并查集操作来确定原始树的连通分量计数。

  • 对于树中的每条边 (u, v),使用并查集数据结构来合并包含顶点 u 和 v 的部分。此步骤建立了树的初始连通性。

  • 从树中删除指定的顶点。

  • 将预处理步骤的并查集操作应用于修改后的树。

  • 删除后,计算并查集数据结构中不同父代表的数量。

  • 结果计数表示树更新后的组件的连通性。

示例

#include <iostream>
#include <vector>

class UnionFind {
public:
   UnionFind(int n) {
      parent.resize(n);
      for (int i = 0; i < n; ++i) {
         parent[i] = i;
      }
   }

   int find(int u) {
      if (parent[u] != u) {
         parent[u] = find(parent[u]);
      }
      return parent[u];
   }

   void unite(int u, int v) {
      int rootU = find(u);
      int rootV = find(v);
      if (rootU != rootV) {
         parent[rootU] = rootV;
      }
   }

   int countDistinctParentRepresentatives() {
      int n = parent.size();
      std::vector<bool> distinct(n, false);
      for (int i = 0; i < n; ++i) {
         distinct[find(i)] = true;
      }
      int count = 0;
      for (bool isDistinct : distinct) {
         if (isDistinct) {
            count++;
         }
      }
      return count;
   }

private:
   std::vector<int> parent;
};

int main() {
   int n = 5;
   UnionFind uf(n);

   uf.unite(0, 1);
   uf.unite(0, 2);
   uf.unite(2, 3);
   uf.unite(2, 4);

   std::cout << uf.countDistinctParentRepresentatives() << 
std::endl;
   return 0;
}

输出

1

结论

总之,提供的方法有效地计算了删除特定顶点后树中连通分量的数量。使用深度优先搜索 (DFS) 方法和并查集方法都可以有效地处理树结构中的连接变化。DFS 方法从选定的顶点开始遍历,标记每个访问的节点,并计算连通分量。删除顶点后,执行新的遍历而不包括已删除的节点,并通过比较遍历前后的计数获得更新后的计数。

并查集方法通过将每个顶点初始化为单独的组件来确定初始连通分量计数,并使用并查集操作。删除顶点后,应用相同的并查集操作,并计算不同的父代表以获得更新后的计数。

两种方法在删除顶点后都提供了对树的连通性的有用见解,并且适用于各种场景。

更新于: 2023-08-04

160 次浏览

开启你的 职业生涯

通过完成课程获得认证

开始学习
广告

© . All rights reserved.