n 個の頂点と m 個のエッジを持つ重み付き無向グラフがあるとします。グラフのスコアは、グラフ内のすべてのエッジの重みの合計として定義されます。エッジの重みは負の値になる場合があり、エッジの重みが削除されると、グラフのスコアが増加します。行う必要があるのは、グラフの接続性を維持しながらグラフ内のエッジを削除して、グラフのスコアを最小化することです。削減できる最大スコアを見つける必要があります。
グラフは配列 'edges' の形式で与えられ、各要素は {weight, {vertex1, vertex2}} の形式になります。
入力が n = 5、m = 6、エッジ = {{2, {1, 2}}、{2, {1, 3}}、{1, {2, 3} の場合}, {3, {2, 4}}, {2, {2, 5}}, {1, {3, 5}}} の場合、出力は 4 になります。
グラフからエッジ (1, 2) と (2, 5) を削除すると、スコアの合計減少量は 4 になり、グラフは接続されたままになります。
この問題を解決するには、次の手順に従います。
cnum := 0 Define an array par of size: 100. Define an array dim of size: 100. Define a function make(), this will take v, par[v] := v dim[v] := 1 Define a function find(), this will take v, if par[v] is same as v, then: return v return par[v] = find(par[v]) Define a function unify(), this will take a, b, a := find(a) b := find(b) if a is not equal to b, then: (decrease cnum by 1) if dim[a] > dim[b], then: swap values of (a, b) par[a] := b dim[b] := dim[b] + dim[a] cnum := n sort the array edges based on edge weights for initialize i := 1, when i <= n, update (increase i by 1), do: make(i) res := 0 for each edge in edges, do: a := first vertex of edge b := second vertex of edge weight := weight of edge if find(a) is same as find(b), then: if weight >= 0, then: res := res + 1 * weight Ignore following part, skip to the next iteration if cnum is same as 1, then: if weight >= 0, then: res := res + 1 * weight Otherwise unify(a, b) return res
理解を深めるために、次の実装を見てみましょう-
#include <bits/stdc++.h> using namespace std; int cnum = 0; int par[100]; int dim[100]; void make(int v){ par[v] = v; dim[v] = 1; } int find(int v){ if(par[v] == v) return v; return par[v] = find(par[v]); } void unify(int a, int b){ a = find(a); b = find(b); if(a != b){ cnum--; if(dim[a] > dim[b]){ swap(a, b); } par[a] = b; dim[b] += dim[a]; } } int solve(int n, int m, vector <pair <int, pair<int,int>>> edges){ cnum = n; sort(edges.begin(), edges.end()); for(int i = 1; i <= n; i++) make(i); int res = 0; for(auto &edge : edges){ int a = edge.second.first; int b = edge.second.second; int weight = edge.first; if(find(a) == find(b)) { if(weight >= 0) res += 1 * weight; continue; } if(cnum == 1){ if(weight >= 0) res += 1 * weight; } else{ unify(a, b); } } return res; } int main() { int n = 5, m = 6; vector <pair<int, pair<int,int>>> edges = {{2, {1, 2}}, {2, {1, 3}}, {1, {2, 3}}, {3, {2, 4}}, {2, {2, 5}}, {1, {3, 5}}}; cout<< solve(n, m, edges); return 0; }
5, 6, {{2, {1, 2}}, {2, {1, 3}}, {1, {2, 3}}, {3, {2, 4}}, {2, {2, 5}}, {1, {3, 5}}}
4
以上がグラフから削減できる最大スコア要素を見つけるための C++ プログラムの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。