信号塔(树形dp)
思路
典中典,看代码
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
vector<pair<int,int> >v[N];
int f[N][2], ans[N];
void dfs(int x, int fa) {
f[x][0] = 0;
f[x][1] = 1;
for(auto y : v[x]) {
if(y.first == fa)continue;
dfs(y.first, x);
f[x][0] += f[y.first][1];
f[x][1] += min(f[y.first][0], f[y.first][1]);
}
}
void dfs2(int x, int fa, int id) {
if(fa) {
int f0 = f[fa][0] - f[x][1], f1 = f[fa][1] - min(f[x][0], f[x][1]);
ans[id] = min(f[x][0], f[x][1]) + min(f0, f1);
f[x][0] += f1;
f[x][1] += min(f1, f0);
}
for(auto y : v[x]) {
if(y.first == fa)continue;
dfs2(y.first, x, y.second);
}
}
int main() {
int T, n, a, b;
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
for(int i = 1; i <= n; i++)
v[i].clear();
for(int i = 1; i < n; i++) {
scanf("%d%d", &a, &b);
v[a].push_back(make_pair(b, i));
v[b].push_back(make_pair(a, i));
}
dfs(1, 0);
dfs2(1, 0, 0);
for(int i = 1; i < n; i++)
printf("%d ", n - ans[i]);
puts("");
}
}