Processing math: 100%

Solução Informática - Nível Avançado - Semana 6

Solução por Thiago Mota

Conhecimento prévio:;

A primeira observação que temos é que como queremos separar em componentes de soma 0 é necessário que a soma total das componentes seja 0, pois se a soma total for diferente de 0 não existe maneira de dividir as componentes.

Imagine que nós removemos uma aresta e dividimos em duas componentes, a única soma possível de cada componente isolada também deve ser 0, pois se a soma das componentes isoladas forem diferente de 0 não existe maneira de divir em componentes menores com soma 0.

Então, temos que remover arestas de forma que a soma sempre se mantenha 0, para isso basta escolher qualquer aresta que a soma das componentes resultantes continue sendo 0. Como o problema é de minimizar o custo, basta escolher as k arestas de menor custo que mantenha a soma sendo 0 após a remoção dela. Segue o código:

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
const int maxn = 1e5 + 10;
int n, k, custo[maxn];
vector<pii> grafo[maxn];
vector<int> arestas; // Arestas que podem ser removidas
int soma[maxn]; // Soma das componentes
void dfs(int u, int p) {
soma[u] = custo[u];
for (int i = 0; i < (int)grafo[u].size(); i++) {
int v = grafo[u][i].first, peso = grafo[u][i].second;
if (v == p) // Se o vizinho for o pai, ignorar ele.
continue;
dfs(v, u);
if (soma[v] == 0) // Se a soma da componente for 0, podemos remover essa aresta.
arestas.push_back(peso); // Guardaremos no vetor de arestas removiveis.
soma[u] += soma[v];
}
}
int main() {
cin >> n >> k;
int soma_custo = 0;
for (int i = 1; i <= n; i++)
cin >> custo[i], soma_custo += custo[i];
if (soma_custo != 0) {
cout << "-1\n";
return 0;
}
for (int i = 1; i < n; i++) {
int a, b, c;
cin >> a >> b >> c;
grafo[a].push_back({b, c});
grafo[b].push_back({a, c});
}
dfs(1, 0);
sort(arestas.begin(), arestas.end()); // Ordenando as arestas removiveis e pegando as k primeiras.
if ( arestas.size() < k ) {
cout << "-1\n";
return 0;
}
int ans = 0;
for (int i = 0; i < k; i++)
ans += arestas[i];
cout << ans << "\n";
return 0;
}
view raw custo.cpp hosted with ❤ by GitHub