首页 > 代码库 > poj 1155(树形dp)
poj 1155(树形dp)
题意:有一个有线电视网络叶子结点是用户,每个用户有一个愿意支付的金额。然后每条边都有话费。问公司在不亏本的情况下最多能满足多少用户。
思路:dp[v][j] = max(dp[v][j], dp[v][j-k]+dp[x][k]-edge(v, x))
其实就是背包问题,但是一开始TLE了一次,这里要有个优化处理一个节点之前需要初始化一下他最多接着几个用户。这样就AC了。
代码如下:
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <algorithm> 5 #include <vector> 6 #include <queue> 7 #include <set> 8 #include <map> 9 #include <string> 10 #include <math.h> 11 #include <stdlib.h> 12 #include <time.h> 13 #define MP(a, b) make_pair(a, b) 14 #define PB(a) push_back(a) 15 using namespace std; 16 const int LEN = 3010; 17 const int INF = 0x3f3f3f3f; 18 typedef pair<int, int> pii; 19 int n, m, dp[LEN][LEN], vex[LEN], num[LEN]; 20 vector<pii> Map[LEN]; 21 22 void dfs(int v, int fa){ 23 if(v > n-m && v <= n) dp[v][1] = vex[v]; 24 for(int i=0; i<Map[v].size(); i++){ 25 int x = Map[v][i].first; 26 if(x != fa){ 27 dfs(x, v); 28 num[v] += num[x]; 29 for(int j=num[v]; j>=0; j--){ 30 for(int k=0; k<=num[x]; k++){ 31 if(j - k >= 0 && dp[x][k] != -INF && dp[v][j-k] != -INF) 32 dp[v][j] = max(dp[v][j], dp[v][j-k]+dp[x][k]-Map[v][i].second); 33 } 34 } 35 } 36 } 37 } 38 39 void init(){ 40 for(int i=0; i<LEN; i++)Map[i].clear(); 41 memset(num, 0, sizeof num); 42 for(int i=0; i<LEN ;i++){ 43 for(int j=0; j<LEN; j++){ 44 dp[i][j] = -INF; 45 if(j == 0) dp[i][j] = 0; 46 } 47 } 48 } 49 50 int main() 51 { 52 // freopen("in.txt","r",stdin); 53 //freopen("out.txt","w",stdout); 54 55 int a, b, tn; 56 while(scanf("%d%d", &n, &m)!=EOF){ 57 init(); 58 for(int i=1; i<=n-m; i++){ 59 scanf("%d", &tn); 60 for(int j=0; j<tn; j++){ 61 scanf("%d%d", &a, &b); 62 Map[i].PB(MP(a, b)); 63 Map[a].PB(MP(i, b)); 64 } 65 } 66 for(int i=n-m+1; i<=n ;i++){ 67 num[i] = 1; 68 scanf("%d", &vex[i]); 69 } 70 dfs(1, -1); 71 int ans; 72 for(int i=m; i>=0; i--){ 73 if(dp[1][i] >= 0){ 74 ans = i; 75 break; 76 } 77 } 78 printf("%d\n", ans); 79 } 80 return 0; 81 82 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。