P2286 [HNOI2004]寵物收養場
阿新 • • 發佈:2018-08-09
題意 per 應該 scan void 可用 play 一個 spl
第一次用set水splay好爽啊!
這道題很明顯,就是弄兩個平衡樹(一個也可以)。
進來一個人,就去另一邊找找前驅和後繼,優先找前驅,找個絕對值最小的配對走。
其實用一下set就可以了啊!
使用std::set.lower_bound
就可以找到x元素,--一下就得到前驅,++一下應該就得到了後繼。
其實後繼也直接可用upper_bound
。
再根據題意模擬一下就能過了。。。
這道題數據特別水。。。
代碼:
#include<cstdio> #include<algorithm> const int maxn = 1005; struct Edges { int next, to, weight; } e[maxn]; int head[maxn], tot; int dp[maxn][maxn]; int n, m; void link(int u, int v, int w) { e[++tot] = (Edges){head[u], v, w}; head[u] = tot; } int dfs(int u) { int ans = 0; for(int i = head[u]; i; i = e[i].next) { int v = e[i].to; int t = dfs(v); ans = ans + t + 1; for(int j = std::min(ans, m); j > 0; j--) { for(int k = std::min(j - 1, ans); k > 0; k--) { dp[u][j] = std::max(dp[u][j], dp[u][j - k - 1] + dp[v][k] + e[i].weight); } } } return ans; } int main() { scanf("%d%d", &n, &m); for(int i = 1; i < n; i++) { int u, v, w; scanf("%d%d%d", &u, &v, &w); link(u, v, w); } dfs(1); printf("%d\n", dp[1][m]); return 0; }
P2286 [HNOI2004]寵物收養場