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
-
C++の二分木で最大垂直和を見つける
二分木があるとします。タスクは、垂直順序トラバーサルのすべてのノードの合計の最大値を出力することです。したがって、ツリーが以下のようになっている場合- 垂直方向の走査は-のようなものです 4 2 1 + 5 + 6 = 12 3 + 8 = 11 7 9 ここでの最大値は12です。アプローチは単純です。垂直順序トラバーサルを実行してから、合計を見つけて最大値を確認します。 例 #include<iostream> #include<map> #include<vector> #include<queue> using namespace
-
C++の完全グラフから可能な最大のエッジの互いに素なスパニングツリー
完全グラフがあるとします。 EdgeDisjointSpanningツリーの数を数える必要があります。 Edge Disjoint Spanningツリーは、セット内の2つのツリーに共通のエッジがないスパニングツリーです。 N(頂点の数)が4であるとすると、出力は2になります。4つの頂点を使用した完全グラフは次のようになります- 2つのエッジのばらばらなスパニングツリーは-のようなものです N個の頂点を持つ完全グラフからのエッジ非結合スパニングツリーの最大数は$[\frac {n} {2}] $になります。 例 #include <iostream> #includ