intdfs(int root){ int sum = 1; for (auto son:nodes[root]) { sum += dfs(son); // TODO: optimize for (int j = sum; j >= 1; j--) { for (int k = 1; k < j; k++) { dp[root][j] = min(dp[root][j], dp[root][j - k] + dp[son][k] - 1); } } } return sum; }
int dset[201];
structEdge { int u, v; };
intmain(){ std::ios::sync_with_stdio(false); std::cin.tie(0); int n, p; cin >> n >> p; int u, v; dset[1] = 1; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { dp[i][j] = n; } } // 构建单向边 map<int, Edge> edge; int cnt = 0; for (int i = 1; i < n; i++) { cin >> u >> v; // 干就完事了 if (u == 1) { nodes[u].insert(v); dset[v] = u; } elseif (v == 1) { nodes[v].insert(u); dset[u] = v; } elseif (dset[u]) { nodes[u].insert(v); dset[v] = 1; } elseif (dset[v]) { nodes[v].insert(u); dset[u] = 1; } else { // 姑且记录一下 edge[cnt].u = u; edge[cnt].v = v; cnt += 1; } } set<int> af; while (!edge.empty()) { for (auto &it:edge) { if (dset[it.second.u]) { nodes[it.second.u].insert(it.second.v); dset[it.second.v] = 1; af.insert(it.first); } elseif (dset[it.second.v]) { nodes[it.second.v].insert(it.second.u); dset[it.second.u] = 1; af.insert(it.first); } } for (auto &it:af) { edge.erase(it); } af.clear(); } // init for (int i = 1; i <= n; i++) { dp[i][1] = nodes[i].size(); } // search dfs(1); int ans = dp[1][p]; #if DISPLAY_A int idx = 1; #endif for (int i = 2; i <= n; i++) { #if DISPLAY_A if (ans > dp[i][p] + 1) { ans = dp[i][p] + 1; idx = i; } #else ans = min(ans, dp[i][p] + 1); #endif } #if DISPLAY_A cout << ans << " " << idx << endl; #else cout << ans << endl; #endif return0; }
测试例生成(Python)
1 2 3 4 5 6 7 8 9 10
defN(n, p, filename='in'): n = int(n) p = int(p) f = open(filename, 'w') f.write("{} {}\r\n{}\r\n".format( n, p, "\r\n".join([ "{} {}".format(random.randint(1, i - 1), i) for i inrange(2, n + 1) ]) ))