Ciao forumari,
ho visto che c’è un altro topic poco sotto, ma è il problema di OP è stato risolto e non voglio andare a rompere le uova nel paniere a una storia conclusa (lol)
Il problema in questione è un minimum vertex cover su un albero con l’aggiuntiva complicazione che a ogni nodo è associato un costo. Pensavo di risolverlo semplicemente lanciando una dfs (dal nodo 1, ma essendo un albero va bene qualunque nodo < n come radice) provando a colorare (piazzare una telecamera) o meno ogni nodo e prendere la soluzione migliore, contando che se non prendo un nodo devo per forza prendere tutti i suoi figli. Memorizzo tutto in un memo, poi rilancio la dfs per stampare la soluzione.
In pseudocodice:
colora(nodo u, nodo padre, bool colore) :
se la soluzione per (u, colore) esiste in memo restituiscila, altrimenti:
se colore = 0 risposta = o, altrimenti risposta = costo di u
per ogni figlio v di u, eccetto il padre:
se colore = 0 risposta += colora(v, u, 1)
altrimenti risposta += min(colora(v, u, 1), colora(v, u, 0)
memo(u, colore) = risposta
restituisci risposta
Ho provato questa soluzione sul testcase dato e funziona, idem su un altro paio di testcase fatti da me, e non riesco a trovare alcuna falla…ma su cms prende solo il caso d’esempio, affermando che esista un costo minore di quello indicato. Potete aiutarmi? Di seguito il codice:
#include <bits/stdc++.h>
using namespace std;
vector<vector<int>> g, memo;
vector<int> cost;
set<int> sol;
int dfs(int u, int color, int t)
{
if (~memo[u][color]) return memo[u][color];
int ans = color * cost[u];
for (auto v : g[u]) {
if (v != t) {
if (color) ans += min(dfs(v, 0, u), dfs(v, 1, u));
else ans += dfs(v, 1, u);
}
}
return memo[u][color] = ans;
}
void print_sol(int u, int t)
{
if (memo[u][0] < memo[u][1]) {
for (auto v : g[u]) {
if (v != t) {
sol.emplace(v);
print_sol(v, u);
}
}
} else {
sol.emplace(u);
for (auto v : g[u]) if (v != t) print_sol(v, u);
}
}
int main()
{
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
size_t n;
int a;
int b;
cin >> n, g.resize(n), cost.resize(n), memo.assign(n, vector<int>(2, -1));
for (size_t i = 0; i < n; i++) cin >> cost[i];
for (size_t i = 0; i < n - 1; i++) {
cin >> a >> b, --a, --b;
g[a].emplace_back(b);
g[b].emplace_back(a);
}
min(dfs(0, 0, -1), dfs(0, 1, -1));
print_sol(0, -1);
cout << sol.size() << "\n";
for (auto i : sol) cout << i + 1 << " ";
cout << "\n";
return 0;
}