poj1155树形dp+背包

来源:互联网 发布:脸型眼镜软件 编辑:程序博客网 时间:2024/06/06 02:18

题目大意:每个用户必须连一个发射器,发射的信号从一个点到另一个点需要费用,问电视台在不亏本的情况下最多可以给多少个用户发射信号。

思路:dp[i][j]表示节点i发射j个信号给用户的盈利。注意:dp数组初始化时,dp[i][0] = 0;其余的负无穷,否则会出bug。自己跟着程序走一遍思路会清晰很多。


#include <iostream>#include <cstdio>#include <string>#include <cstring>#include <fstream>#include <algorithm>#include <cmath>#include <queue>#include <stack>#include <vector>#include <map>#include <set>#include <iomanip>using namespace std;//#pragma comment(linker, "/STACK:102400000,102400000")#define maxn 3005#define MOD 1000000007#define mem(a , b) memset(a , b , sizeof(a))#define LL long long#define INF 100000000int n , id , m;int res[maxn] , tmp[maxn];struct edge{    int u , v , w;    int next;}E[maxn];int head[maxn];int dp[maxn][maxn];int val[maxn];void add(int u , int v , int w){    E[id].u = u;    E[id].v = v;    E[id].w = w;    E[id].next = head[u];    head[u] = id++;}void dfs(int root){    for(int i = head[root] ; i != -1 ; i = E[i].next)    {        dfs(E[i].v);        for(int j = 0 ; j <= res[root] ; j ++) tmp[j] = dp[root][j];        for(int j = 0 ; j <= res[root] ; j ++)        {            for(int k = 1 ; k <= res[E[i].v] ; k ++)            {                dp[root][j+k] = max(dp[root][j+k] , tmp[j] + dp[E[i].v][k] - E[i].w);            }        }        res[root] += res[E[i].v];    }//    cout << root << ":" << endl;//    for(int i = 0 ; i <= res[root] ; i ++) cout << dp[root][i] << " ";//    cout << endl;}int main(){    while(scanf("%d %d" , &n , &m)!= EOF)    {        id = 0;        mem(head , -1);        mem(dp , 0);        for(int i = 1 ;i <= n ; i ++)        {            for(int j = 1 ; j <= m ;j ++)                dp[i][j] = -MOD;        }        int v , w , up = n - m , num;        for(int i = 1 ; i <= up ; i ++)        {            scanf("%d" , &num);            for(int j = 0 ; j < num ; j  ++)            {                scanf("%d %d" , &v , &w);                add(i , v , w);            }            res[i] = 0;        }        for(int i = up+1 ; i <= n ; i ++) {scanf("%d" , &val[i]) ; dp[i][1] = val[i] ; res[i] = 1;}        dfs(1);        for(int i = m ; i >= 0 ; i --)        {           // cout << dp[1][i] << endl;            if(dp[1][i] >= 0)            {                printf("%d\n" , i);                break;            }        }    }    return 0;}


0 0
原创粉丝点击