树形DP [POJ 1155] TELE

TELE

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 3787   Accepted: 2007

Description

A TV-network plans to broadcast an important football match. Their network of transmitters and users can be represented as a tree. The root of the tree is a transmitter that emits the football match, the leaves of the tree are the potential users and other vertices in the tree are relays (transmitters).  The price of transmission of a signal from one transmitter to another or to the user is given. A price of the entire broadcast is the sum of prices of all individual signal transmissions.  Every user is ready to pay a certain amount of money to watch the match and the TV-network then decides whether or not to provide the user with the signal.  Write a program that will find the maximal number of users able to watch the match so that the TV-network‘s doesn‘t lose money from broadcasting the match.

Input

The first line of the input file contains two integers N and M, 2 <= N <= 3000, 1 <= M <= N-1, the number of vertices in the tree and the number of potential users.  The root of the tree is marked with the number 1, while other transmitters are numbered 2 to N-M and potential users are numbered N-M+1 to N.  The following N-M lines contain data about the transmitters in the following form:  K A1 C1 A2 C2 ... AK CK  Means that a transmitter transmits the signal to K transmitters or users, every one of them described by the pair of numbers A and C, the transmitter or user‘s number and the cost of transmitting the signal to them.  The last line contains the data about users, containing M integers representing respectively the price every one of them is willing to pay to watch the match.

Output

The first and the only line of the output file should contain the maximal number of users described in the above text.

Sample Input

9 6
3 2 2 3 2 9 3
2 4 2 5 2
3 6 2 7 2 8 2
4 3 3 3 1 1

Sample Output

5

Source

Croatia OI 2002 Final Exam - Second Day

树形背包、注意理解、上代码 - -

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
#define INF 0x7ffffff
#define ll long long
#define N 3010

struct Edge
{
    int to,next,len;
}edge[N];
int head[N],tot;

int n,m;
int val[N];
int num[N];
int dp[N][N]; /* dp[i][j]表示在节点i为根节点的子树,有j个叶子节点时的最大利润  */
              /* 状态转移方程: dp[i][j] = max(dp[i][j], dp[i][k]+dp[son][j-k]-w[i][son]); */
void init()
{
    tot=0;
    memset(head,-1,sizeof(head));
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            dp[i][j]=-INF;
        }
    }
}
void add(int x,int y,int z)
{
    edge[tot].to=y;
    edge[tot].len=z;
    edge[tot].next=head[x];
    head[x]=tot++;
}
void dfs(int u)
{
    if(head[u]==-1)
    {
        num[u]=1;
        dp[u][1]=val[u];
    }
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].to;
        int w=edge[i].len;
        dfs(v);
        num[u]+=num[v];
        for(int j=num[u];j>=0;j--)
        {
            for(int k=0;k<=j;k++)
            {
                dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k]-w);
            }
        }
    }
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        init();
        for(int i=1;i<=n-m;i++)
        {
            int a,b,c;
            scanf("%d",&c);
            for(int j=0;j<c;j++)
            {
                scanf("%d%d",&a,&b);
                add(i,a,b);

            }
        }
        for(i=n-m+1;i<=n;i++)
        {
            scanf("%d",&val[i]);
        }
        dfs(1);

        for(int i=m;i>=0;i--)
        {
            if(dp[1][i]>=0)
            {
                printf("%d\n",i);
                break;
            }
        }
    }
    return 0;
}
时间: 2024-12-20 13:29:45

树形DP [POJ 1155] TELE的相关文章

POJ 1155 TELE 树形背包问题

题目描述看的莫名其妙,很久才看懂. 就是很裸的树形背包问题吧,状态是dp(i,j)表示节点i取到j个客户能得到的最大收益. 注意一开始初始化的时候所有j为0的时候应该是0,然后其他值都要初始化成负无穷,因为收益有可能是负值. 然后做01背包的时候注意方向,防止出现取某一个元素多次 #include <cstdio> #include <cstring> #include <iostream> #include <map> #include <set&g

[POJ 1155] TELE (树形dp)

题目链接:http://poj.org/problem?id=1155 题目大意:电视台要广播电视节目,要经过中转机构,到观众.从电视台到中转商到观众是一个树形结构,经过一条边需要支付成本.现在给你每两个节点之间传播的成本,给你每个观众会付的钱,问你电视台在不亏本的情况下最多能给多少个观众看节目. 这是我的第一道树形dp..无耻的看了题解.. 设计状态:dp[u][i]代表以u为根的子树中有i个观众,能够得到的最大收入. 状态转移:dp[u][i] = max(dp[u][i],dp[u][i-

POJ 1155 TELE 背包型树形DP 经典题

由电视台,中转站,和用户的电视组成的体系刚好是一棵树 n个节点,编号分别为1~n,1是电视台中心,2~n-m是中转站,n-m+1~n是用户,1为root 现在节点1准备转播一场比赛,已知从一个节点传送数据到达另一个节点,电视台需要一定的费用 若可以传送数据到达用户的节点n-m+1~n,这些用户各自愿意支付一定的费用给电视台 现在电视台希望在不亏本的情况下为尽量多的用户转播比赛 输出最多可以为多少用户转播比赛 背包类型的树形DP第一题 dp[i][j]表示以节点i为根的子树有j个用户获得转播,电视

poj 1155 TELE(树形泛化背包dp)

/* 这道题还不错,自己想出了思路过得也比较快,也得出了一个小经验,以后写这种题先把关键部分伪代码写出来这样会快很多而且 不那么容易出错,省去很多的调试时间 这道题就是转化为一道树形背包问题.首先把需要付的钱转为负数,对每个叶子结点增加一个子节点表示赚的钱,为正数. 然后记录下当前结点的所有可能的用户数目所花费的钱.所以问题就转化为一道简单的树形dp问题.最后找出盈利为非负数的最大 用户数即可. 有一点要注意dp数组初始化为一个很大的负数,刚开始因为这个问题wa了一遍 用到了num数组存放每个结

POJ 1155 TELE

TELE Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged on PKU. Original ID: 115564-bit integer IO format: %lld      Java class name: Main A TV-network plans to broadcast an important football match. Their network of transmitters an

树形dp poj 2342

题目链接:poj 2342 题目大意:某公司要举办一次晚会,但是为了使得晚会的气氛更加活跃,每个参加晚会的人都不希望在晚会中见到他的直接上司,现在已知每个人的活跃指数和上司关系(当然不可能存在环),求邀请哪些人(多少人)来能使得晚会的总活跃指数最大. 思路:既然是树形dp,自然先建立一颗树了,这里用的是邻接表(L<-K).找根的时候利用flag数组来标记所有儿子节点,那么没有标记的自然是根节点了.树形dp从叶子节点开始dp,所以深搜到叶子节点,然后不断回溯给父节点.在处理儿子节点时,父节点不参加

POJ 1155 TELE (树形DP,树形背包)

题意:给定一棵树,n个节点,其中有m个叶子表示的是用户,其他点表示中转器, 每条边都有权值,每个用户i愿意给的钱w[i],问如果在不亏钱的情况下能为多少用户转播足球比赛? 思路: 其实就是要选出部分叶子节点,其花费=所选叶子权值 - 经过的所有边权(每条边只算1次花费). 那么对于每个节点,可以考虑在其子树下选择1~k个叶子节点,记录下dp值(是个最优值).那么就需要枚举所有可能了.复杂度貌似在极端情况下还是挺高的,比如单链1000个节点+2000个叶子节点的情况,不会算复杂度,每个非叶子节点中

POJ 1155 TELE 树形背包

链接:http://poj.org/problem?id=1155 题意:电视台转播一场重要的足球比赛,以这个转播机器为根建立一棵"转播树",数中一共有N个(N<=3000),叶子节点是所有用户,有M个用户(M<=N-1),每个用户有固定的付费额度.除了用户以外的结点都是转接信号的机器,在所有结点之间连线都需要有一定的花费.现在要求我尽可能满足更多人的观看要求,并且保证转播不赔钱.问最多可以保证多少人的观看要求. 思路:从叶到根依次记录当前结点可以满足的观看要求的数量,并且

树形DP [POJ 1947] Rebuilding Roads

Rebuilding Roads Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 9249   Accepted: 4198 Description The cows have reconstructed Farmer John's farm, with its N barns (1 <= N <= 150, number 1..N) after the terrible earthquake last May. The