zoukankan      html  css  js  c++  java
  • poj 1155 TELE 树形dp ****

    TELE
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 3230   Accepted: 1655

    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

     
    题意: 一个电视网络公司,要给尽可能的用户提供TV。但是,其他是不亏本呀。
       1是总站,其他点是  用户  或者是  中转站。
       中转站和用户的点都要钱建立路线,而每个用户出的钱又是不同的。
     
    思路: 用一个数组val[ ] 保存 最后各个点的值就可以了。
    对于用户的节点:
            val[] = 用户出的钱- 建立线路的钱。
    对于中转站的节点:
            val[]= 0  - 建立线路的钱。
     
    dp[ k ] [ j ] 表示以k为根节点,给 J 个用户提供TV,盈利的钱。
     
    对于叶子节点 dp[ k ] [ 1 ]= val [ k ];
    非叶子节点    dp[ k ] [ 0 ]= val [ k ]; //???仔细想一想吧。
     
    if( j>=s && dp [ k ] [ j - s ]!= -INF )
    dp[ k ] [ j ] = max(  dp [ k ] [ j ]  ,    dp [ k ] [ j - s] + dp [ t ] [ s ])
     
    :修改了好久代码,不过写出来,感觉不错。
     
     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<stdlib.h>
     4 #define INF 1000000
     5 int n,m;
     6 int val[3003];
     7 struct node
     8 {
     9     int next[3003];
    10     int num;
    11 }f[3003];
    12 int dp[3003][3003];
    13 int Num[3003];
    14 
    15 int Max(int x,int y)
    16 {
    17     return x>y? x:y;
    18 }
    19 
    20 void dfs(int k)
    21 {
    22     int i,j,t,s;
    23     if(f[k].num==0)
    24         dp[k][1]=val[k];
    25     else
    26         dp[k][0]=val[k];
    27 
    28     for(i=1;i<=f[k].num;i++)
    29     {
    30         t=f[k].next[i];
    31         dfs(t);
    32         Num[k]+=Num[t];
    33     //    printf("%d  Num[k]: %d
    ",k,Num[k]);
    34    //     system("pause");
    35         for(j=Num[k];j>=1;j--)
    36         {
    37             for(s=1;s<=Num[t];s++)
    38             {
    39                 if(j>=s && dp[k][j-s]!=-INF)
    40                 dp[k][j]=Max(dp[k][j],dp[k][j-s]+dp[t][s]);
    41             }
    42         }
    43     }
    44 }
    45 
    46 int main()
    47 {
    48     int i,j,t,x,y;
    49     while(scanf("%d%d",&n,&m)>0)
    50     {
    51         memset(val,0,sizeof(val));
    52         memset(Num,0,sizeof(Num));
    53         for(i=0;i<=n;i++)
    54         for(j=0;j<=n;j++)
    55         dp[i][j]=-INF;
    56         for(i=0;i<=n;i++)
    57         f[i].num=0;
    58 
    59         int k=n-m;
    60         for(i=1;i<=k;i++)
    61         {
    62             scanf("%d",&t);
    63             f[i].num=t;
    64             Num[t]=0;
    65             for(j=1;j<=t;j++)
    66             {
    67                 scanf("%d%d",&x,&y);
    68                 f[i].next[j]=x;
    69                 val[x]=-y;
    70             }
    71         }
    72         for(i=n-m+1;i<=n;i++)
    73         {
    74             scanf("%d",&x);
    75             val[i]=val[i]+x;
    76             Num[i]=1;
    77         }
    78         val[1]=0;
    79         dfs(1);
    80         for(i=m;i>=1;i--)
    81         {
    82             if(dp[1][i]>=0)
    83             {
    84                 printf("%d
    ",i);
    85                 break;
    86             }
    87         }
    88     }
    89     return 0;
    90 }
     
     
     
     
  • 相关阅读:
    python设计模式-单例模式
    bash脚本条件测试总结
    Python网络编程:IO多路复用
    Python面向对象高级编程:@property--把方法变为属性
    Sql Server存储过程基本语法
    接口幂等性
    [转载]使用消息队列实现分布式事务-公认较为理想的分布式事务解决方案
    C#分布式事务解决方案-TransactionScope
    SOA架构和微服务架构的区别
    Atlas实现数据库读写分离
  • 原文地址:https://www.cnblogs.com/tom987690183/p/3400487.html
Copyright © 2011-2022 走看看