码迷,mamicode.com
首页 > 其他好文 > 详细

luogu P1273 有线电视网

时间:2018-04-17 21:20:35      阅读:197      评论:0      收藏:0      [点我收藏+]

标签:oid   树形背包   print   ext   cst   void   clu   show   获得   

题目链接

luogu P1273 有线电视网

题解

树形背包
dp[i][j]表示在以i为根的子树中,满足j个客户的需求所能获得的最大收益

代码

#include<cstdio>
#include<algorithm>
#include<cstring>
const int maxn = 3007;

//using namespace std;
inline int read() {
    int x = 0,f = 1;
    char c = getchar();
    while(c < '0' || c > '9'){ if(c == '-') f = -1; c = getchar(); }
    while(c <= '9' && c >= '0') x = x * 10 + c - '0', c = getchar();
    return x * f; 
}
int n , m;
struct Node {
    int v , w, next;            
}edge[maxn << 1];
int num , head[maxn];
inline void add_edge(int u,int v,int w) {edge[++ num].v = v,edge[num].w = w;edge[num].next = head[u];head[u] = num; }
int cost[maxn],son[maxn];
int dp[maxn][maxn];
void dfs(int u,int fa) { 
    dp[u][0] = 0;
    if(u >= n - m + 1) {
        dp[u][1] = cost[u]; 
        son[u] = 1; return; 
    }
    for(int num = 0,i = head[u]; i ;i = edge[i].next) {
        int v = edge[i].v;
        if(v == fa) continue;
        dfs(v,u); 
        son[u] += son[v];
        for(int j = son[u];j >= 1; --j)
            for(int k = 0;k <= std::min(son[v],j);++ k) 
                dp[u][j] = std::max(dp[u][j],dp[u][j - k] + dp[v][k] - edge[i].w);
    }
}
int main() {
    memset(dp,-0x3f,sizeof dp);
    //printf("%d\n",dp[1][0]);
    n = read(),m = read();
    for(int k,i = 1;i <= n - m;++ i) {
        k = read();
        for(int v,w,j = 1;j <= k;++ j) {
            v = read(),w = read();
            add_edge(i,v,w);
            add_edge(v,i,w);
        }
    }
    for(int i = n - m + 1;i <= n; ++i ) cost[i] = read();
    dfs(1,1);
    for(int i = m;i >= 0; -- i) if(dp[1][i] >= 0)  { printf("%d\n",i);break; }
    return 0;
}       

luogu P1273 有线电视网

标签:oid   树形背包   print   ext   cst   void   clu   show   获得   

原文地址:https://www.cnblogs.com/sssy/p/8870013.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!