zoukankan      html  css  js  c++  java
  • HDU 1520 树形DP入门

    HDU 1520

    【题目链接】HDU 1520

    【题目类型】树形DP

    &题意:

    某公司要举办一次晚会,但是为了使得晚会的气氛更加活跃,每个参加晚会的人都不希望在晚会中见到他的直接上司,现在已知每个人的活跃指数和上司关系(当然不可能存在环),求邀请哪些人(多少人)来能使得晚会的总活跃指数最大。

    &题解:

    poj有一个一样的题,被那个坑了,看的是那个的代码,之后提交hdu总是超时,最后发现递归的时候总是循环n遍,所以才超的时。
    只要存下每个节点的孩子就好了,但father数组还是要用的,因为要用它来求根是哪个。(或许也可以不用,但是我没想到)

    &代码:

    #include <iostream>
    #include <cstdio>
    #include <vector>
    #include <cstring>
    #include <map>
    #include <set>
    #include <queue>
    #include <cmath>
    #include <algorithm>
    #define cle(a,v) memset(a,(v),sizeof(a))
    #define ll long long
    const int maxn = 6000 + 7;
    int n, dp[maxn][2], father[maxn], u, v;
    bool vis[maxn];
    std::vector<int> ch[maxn];
    void tree_dp(int u) {
    	vis[u] = 1;
    	for (int i = 0; i < ch[u].size(); i++) {
    		if (!vis[ch[u][i]] && father[ch[u][i]] == u) {
    			tree_dp(ch[u][i]);
    			dp[u][1] += dp[ch[u][i]][0];
    			dp[u][0] += std::max(dp[ch[u][i]][1], dp[ch[u][i]][0]);
    		}
    	}
    }
    int main() {
    	freopen("1.in", "r", stdin);
    	while (~scanf("%d", &n)) {
    		for (int i = 1; i <= n; i++)
    			ch[i].clear();
    		memset(father, -1, sizeof(father));
    		memset(vis, 0, sizeof(vis));
    		memset(dp, 0, sizeof(dp));
    		for (int i = 1; i <= n; i++) {
    			scanf("%d", &dp[i][1]);
    		}
    		int root = 1;
    		while (scanf("%d%d", &u, &v), u || v) {
    			father[u] = v;
    			ch[v].push_back(u);
    		}
    		while (father[root] != -1) root = father[root];
    		// printf("%d
    ", root);
    		tree_dp(root);
    		printf("%d
    ", std::max(dp[root][1], dp[root][0]));
    	}
    	return 0;
    }
    
  • 相关阅读:
    2016/3/10 Java 错题
    2016/3/9 Java 错题集
    Java Socket 编程实验总结
    CSU 1290
    CSU 1307
    CSU 1060
    Problem B SPOJ DCEPC11I
    activemq 学习系列(二) 常用配置
    activemq 学习系列(一) 详细入门使用
    MySql 用户创建与授权
  • 原文地址:https://www.cnblogs.com/s1124yy/p/7259767.html
Copyright © 2011-2022 走看看