Computer >> 컴퓨터 >  >> 프로그램 작성 >> C++

모든 노드 제거에 필요한 예상 작업 수를 계산하는 C++ 프로그램

<시간/>

방향 그래프 G의 인접 행렬이 있다고 가정합니다. 그래프가 비어 있을 때까지 다음 작업을 반복합니다. G에서 하나의 정점을 선택한 다음 해당 정점과 일부 가장자리를 따라 해당 정점에서 도달할 수 있는 모든 정점을 지웁니다. 꼭짓점을 지우면 해당 꼭짓점에 발생한 가장자리도 지워집니다. 작업이 완료되는 예상 횟수를 찾아야 합니다.

따라서 입력이 다음과 같으면

모든 노드 제거에 필요한 예상 작업 수를 계산하는 C++ 프로그램

그러면 출력은 1.6667이 됩니다. 처음에는 정점 A를 선택하고 모든 정점을 제거하고 정점 B를 선택하면 B와 C를 제거하고 두 번째 작업에서 A를 선택하여 제거하기 때문에 출력은 1.6667이 됩니다. 마찬가지로 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