HDU 2412 Party at Hali-Bula 树形DP

来源:互联网 发布:java实例编程题题库 编辑:程序博客网 时间:2024/06/08 06:41

Problem:
有一颗上下级关系的书,对于每一个节点来说,它和它的直系上级不能同时存在,问这棵树最多有多少个节点可以同时存在。
Solution:
对于每一颗子树,如果求出来这颗子树选和不选的两种情况的最大值,那么的父节点对应的就是,如果选父节点,那就把它所有子节点不选的最大值相加,如果不选父节点,那就把所有子节点中两种情况的最大值相加,对于选了的子节点的情况,看对应情况中是否有多种选择。
notes:
在树上的dp数据结构可以利用动态二维数组实现,对于每一个结点附一个权值,进行记忆化搜索。

#include<cstdio>#include<iostream>#include<sstream>#include<cstdlib>#include<cmath>#include<cctype>#include<string>#include<cstring>#include<algorithm>#include<stack>#include<queue>#include<set>#include<map>#include<ctime>#include<vector>#include<fstream>#include<list>using namespace std;typedef long long ll;typedef unsigned long long ull;#define ms(s) memset(s,0,sizeof(s))const double PI = 3.141592653589;const int INF = 0x3fffffff;struct Node {    int fw = 0, tw = 1;    bool hasView = false, fhasSelect = false, thasSelect = false;};map<string, Node> nodes;map<string, vector<string> > G;int dp(string name, int flag) {//flag为1代表选,0代表不选    Node &tnode = nodes[name];    if(!tnode.hasView) {        vector<string> &tg = G[name];        for(int i = 0; i < tg.size(); i++) {            tnode.tw += dp(tg[i], 0);            if(nodes[tg[i]].fhasSelect)                tnode.thasSelect = true;            if(dp(tg[i], 0) == dp(tg[i], 1)) {                tnode.fw += dp(tg[i], 0);                tnode.fhasSelect = true;            }            else if(dp(tg[i], 1) > dp(tg[i], 0)) {                tnode.fw += dp(tg[i], 1);                if(nodes[tg[i]].thasSelect)                    tnode.fhasSelect = true;            }            else {                tnode.fw += dp(tg[i], 0);                if(nodes[tg[i]].fhasSelect)                    tnode.fhasSelect = true;            }        }        tnode.hasView = true;    }    if(flag == 1)        return tnode.tw;    else        return tnode.fw;}int main() {//        freopen("/Users/really/Documents/code/input","r",stdin);    //    freopen("/Users/really/Documents/code/output","w",stdout);        ios::sync_with_stdio(false);    int n;    string boss, son, father;    while(cin >> n) {        if(n == 0)            break;        nodes.clear();  G.clear();        cin >> boss;        nodes[boss] = Node();        for(int i = 1; i < n; i++) {            cin >> son >> father;            G[father].push_back(son);            nodes[son] = Node();        }        if(dp(boss, 0) == dp(boss, 1)) {            cout << dp(boss, 0) << " No" << endl;        }        else if(dp(boss, 0) > dp(boss, 1)) {            if(nodes[boss].fhasSelect)                cout << dp(boss, 0) << " No" << endl;            else                cout << dp(boss, 0) << " Yes" << endl;        }        else {            if(nodes[boss].thasSelect)                cout << dp(boss, 1) << " No" << endl;            else                cout << dp(boss, 1) << " Yes" << endl;        }    }    return 0;}
1 0