C++程序计算删除所有节点所需操作的期望次数


假设我们有有向图 G 的邻接矩阵。在图变为空之前,我们重复执行以下操作:从 G 中选择一个顶点,然后擦除该顶点和所有可以通过跟随一些边从该顶点到达的顶点。擦除一个顶点也将擦除与其关联的边。我们必须找到操作执行的期望次数。

因此,如果输入类似于

则输出将为 1.6667,因为最初选择顶点 A,删除所有顶点,如果我们选择顶点 B,删除 B 和 C,在第二次操作中选择 A 以删除它,类似地,通过选择 C 也需要 2 次操作。因此平均值为 (1+2+2)/3 = 1.6667。

步骤

为了解决这个问题,我们将遵循以下步骤 -

n := size of G
for initialize i := 0, when i < n, update (increase i by 1), do:
   G[i, i] := 1
for initialize k := 0, when k < n, update (increase k by 1), do:
   for initialize i := 0, when i < n, update (increase i by 1), do:
      for initialize j := 0, when j < n, update (increase j by 1), do:
         if G[i, k] is non-zero and G[k, j] is non-zero, then:
            G[i, j] := 1
         ans := 0
      for initialize i := 0, when i < n, update (increase i by 1), do:
         k := 0
      for initialize j := 0, when j < n, update (increase j by 1), do:
         if G[j, i] is non-zero, then:
            (increase k by 1)
         ans := ans + 1.0 / k
return ans

示例

让我们看一下以下实现以获得更好的理解 -

#include <bits/stdc++.h>
using namespace std;

double solve(vector<vector<int>> G){
   int n = G.size();
   for (int i = 0; i < n; ++i)
      G[i][i] = 1;
   for (int k = 0; k < n; ++k)
      for (int i = 0; i < n; ++i)
         for (int j = 0; j < n; ++j)
            if (G[i][k] && G[k][j])
               G[i][j] = 1;
   double ans = 0;
   for (int i = 0; i < n; ++i){
      int k = 0;
      for (int j = 0; j < n; ++j)
         if (G[j][i])
            ++k;
         ans += 1.0 / k;
   }
   return ans;
}
int main(){
   vector<vector<int>> G = { { 0, 1, 0 }, { 0, 0, 1 }, { 0, 1, 0 }};
   cout << solve(G) << endl;
}

输入

{ { 0, 1, 0 }, { 0, 0, 1 }, { 0, 1, 0 } }

输出

1.66667

更新于: 2022年3月3日

109 次查看

开启你的 职业生涯

通过完成课程获得认证

立即开始
广告