贴一个贪心做法,不知道对不对(不会用dp解决), 从底层结点往上找,如果它的状态是开灯的话,那么它最优解肯定是它的父节点以及父节点的父节点,否则就是它本身和父节点(如果父节点状态是开灯的情况下)
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pi = pair<ll, ll>;
using ld = long double;
const int N = 1e6+ 10;
int mod = 1e9 + 7;
ll n,m;
ll a[N];
vector<int> g[N];
int fa[N];
vector<int> ceng[N];
int mx = 0;
void dfs(int cur, int faa, int c) {
ceng[c].push_back(cur);
fa[cur] = faa;
mx = max(mx, c);
for(auto i: g[cur]) {
if(i == faa) continue;
dfs(i, cur, c + 1);
}
}
void solve()
{
cin >> n;
for(int i = 1; i < n; i++) {
int u, v;
cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1, -1, 0);
vector<pi> t;
vector<bool> v(n+5, 0);
for(int i = mx; i >= 0; i--) {
for(auto j: ceng[i]) {
if(v[j]) continue;
int FA = fa[j];
if(FA == -1 || v[FA]) continue;
int FFA = fa[FA];
if(FFA == -1 || v[FFA]) {
t.push_back({j, FA});
v[j] = 1;
v[FA] = 1;
}
else {
t.push_back({FFA, FA});
v[FFA] = 1;
v[FA] = 1;
}
}
}
cout << t.size() << '\n';
for(auto i: t) {
cout << i.first << ' ' << i.second << '\n';
}
}
int main()
{
// 请在此输入您的代码
ios::sync_with_stdio(0);
cin.tie(0);
int _ = 1;
// cin >> _;
while(_--) solve();
}