HackerRank Even Tree(树dp)

来源:互联网 发布:人工智能产品有哪些 编辑:程序博客网 时间:2024/06/04 23:20

题目链接:点击打开链接

思路:

简单证明了一下,贪心不可行,  那么我们考虑树形dp。   用d[u]表示以u为根的子树的最优解。 u的儿子v,如果以v为根的子树数目为偶数, 那么可以考虑选择断掉u和v的边(决策1), 也可以不断, 递归下去(决策2)。

细节参见代码:

#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>#include <string>#include <vector>#include <stack>#include <ctime>#include <bitset>#include <cstdlib>#include <cmath>#include <set>#include <list>#include <deque>#include <map>#include <queue>#define Max(a,b) ((a)>(b)?(a):(b))#define Min(a,b) ((a)<(b)?(a):(b))using namespace std;typedef long long ll;typedef long double ld;const double eps = 1e-6;const double PI = acos(-1);const int mod = 1000000000 + 7;const int INF = 0x3f3f3f3f;// & 0x7FFFFFFFconst int seed = 131;const ll INF64 = ll(1e18);const int maxn = 100+10;int sum[maxn],T,n,m,d[maxn],vis[maxn],kase = 0;vector<int> g[maxn];int dfs(int u, int fa) {    int len = g[u].size();    sum[u] = 1;    for(int i = 0; i < len; i++) {        int v = g[u][i];        if(v == fa) continue;        sum[u] += dfs(v, u);    }    return sum[u];}int dp(int u, int fa) {    int& ans = d[u];    if(vis[u] == kase) return ans;    vis[u] = kase;    ans = 0;    int len = g[u].size();    if(len == 0) return -INF;    for(int i = 0; i < len; i++) {        int v = g[u][i];        if(v == fa) continue;        if(!(sum[v]&1)) ans = max(ans, ans+1);        ans = max(ans, ans+dp(v, u));    }    return ans;}int main() {    scanf("%d%d", &n, &m);    for(int i = 1; i <= m; i++) {        int u, v;        scanf("%d%d", &u, &v);        g[u].push_back(v);        g[v].push_back(u);    }    ++kase;    dfs(1, 1);    int ans = dp(1, 1);    printf("%d\n", ans);    return 0;}


0 0