hdu 5148 Cities(树形dp)
2015-01-03 21:58
337 查看
题目链接:hdu 5148 Cities
dp[i][j]表示以i为根节点,选j个最优值,每条边被选中的时候就计算出被经过的次数,并乘上权值。
dp[i][j]表示以i为根节点,选j个最优值,每条边被选中的时候就计算出被经过的次数,并乘上权值。
#include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; typedef pair<int, int> pii; typedef long long ll; const int maxn = 2005; int N, K; ll ans, dp[maxn][55]; vector<pii> g[maxn]; void cmin(ll& v, ll x) { if (v == -1 || v > x) v = x; } void init () { scanf("%d%d", &N, &K); ans = -1; memset(dp, -1, sizeof(dp)); for (int i = 1; i <= N; i++) g[i].clear(); int a, b, c; for (int i = 1; i < N; i++) { scanf("%d%d%d", &a, &b, &c); g[a].push_back(make_pair(b, c)); g[b].push_back(make_pair(a, c)); } } void dfs(int u, int f) { dp[u][1] = 0; for (int i = 0; i < g[u].size(); i++) { int v = g[u][i].first; int w = g[u][i].second * 2; if (v == f) continue; dfs(g[u][i].first, u); for (int k = K - 1; k; k--) { if (dp[u][k] == -1) continue; for (int j = 1; j + k <= K; j++) { if (dp[v][j] == -1) continue; cmin(dp[u][k+j], dp[u][k] + dp[v][j] + w * (K - j) * j); } } } if (dp[u][K] != -1) cmin(ans, dp[u][K]); } int main () { int cas; scanf("%d", &cas); while (cas--) { init(); dfs(1, 0); printf("%I64d\n", ans); } return 0; }
相关文章推荐
- hdu 5148 cities 树形DP
- HDU 5148 Cities 树形DP(背包)
- hdu 5148 Cities(树形背包)
- 【树形DP】 HDOJ 5148 Cities
- hdu 5148 树形dp,分组背包
- hdu 5148 City (树形dp)
- hdu 1495 Anniversary party __树形DP
- hdu 3245 zoj zju 3188 树形DP
- hdu 1011 树形DP
- hdu 4123 树形dp (最小途径+次小途径+最小逆向途径)+RMQ
- hdu 1011 Starship Troopers 树形dp
- hdu 4003 Find Metal Mineral(树形DP)
- hdu 1011 Starship Troopers(树形DP)
- 【树形DP---未解决】hdu 3660
- HDU 1520 Anniversary party【树形DP】
- HDU 1561 The more, The Better【树形DP】
- hdu 2415 Bribing FIPA(树形DP)
- 树形DP---hdu 1520 Anniversary Party
- hdu 1011 ,hdu 1561,树形DP
- hdu 1011 Starship Troopers(树形dp)