poj 3342 Party at Hali-Bula 树形dp

来源:互联网 发布:android 录屏软件 编辑:程序博客网 时间:2024/04/30 13:19

poj 3342 Party at Hali-Bula

http://poj.org/problem?id=3342

题意:给定一些点,这些点最多只有一个父节点,且只有一个点没有父节点,要选择一个集合使点数最多,且不能同时选择子节点与其对应的父节点

 

树形dp状态转移很好写,只是中间的选择是否唯一纠结了一下,见注释

 

另外忘记了些mp.clear()。。。。wa了好多次。。。。以后要细心。。。。

还有就是赶上了昨天poj崩溃呀~~~~~~~~除了3800和3801一片RE~~~啦啦啦~~~~

 

#include <iostream>#include <cstdio>#include <algorithm>#include <map>#include <cstring>using namespace std;const int maxn= 310;struct node{    int v, next;}edge[maxn];int dp[maxn][2], vis[maxn], pre[maxn], value, n, flag;map<string, int> mp;void add( int aa, int bb){    edge[value].v= aa;    edge[value].next= pre[bb];    pre[bb]= value++;}void init(){    int i, j, k, cnt= 1, aa, bb;    char tmp1[110], tmp2[110];    mp.clear();                  // STL 全局变量 记着clear......................    memset( vis, 0, sizeof( vis));    memset( dp, 0, sizeof( dp));    memset( pre, -1, sizeof( pre));    value= 1;    scanf("%s", tmp1);    mp[tmp1]= cnt++;    for( i= 1; i<n; i++){        scanf("%s%s", tmp1, tmp2);        if( !mp[tmp1]) mp[tmp1]= cnt++;        if( !mp[tmp2]) mp[tmp2]= cnt++;        aa= mp[tmp1];        bb= mp[tmp2];        add(aa, bb);    }}int MAX(int x, int y){    return x>y?x:y;}void dfs(int u){    int i, j, k, p;    if( vis[u]) return;    vis[u]= 1;    for( j= pre[u]; j!= -1; j= edge[j].next){        p= edge[j].v;        dfs(p);        dp[u][1]+= dp[p][0];        dp[u][0]+= MAX( dp[p][0], dp[p][1]);    }    dp[u][1]++;}int check(){    int i, j, k;    for( i=1; i<=n; i++){        //注意1节点,为根,没有父节点        //所以要考虑其dp[1][1]== dp[1][0]情况时,需特殊处理        //在main函数中先判断了dp[1][1]== dp[1][0],才觉得要不要进入check函数        if( dp[i][0] >= dp[i][1]){            //对于某个节点,当满足此种情况时,应选择dp[i][0],            //而dp[u][0]为的累加和 MAX( dp[p][0], dp[p][1])            //若dp[p][0]==dp[p][1]时,即子节点选与不选结果相同,即不唯一            for( j= pre[i]; j!= -1; j= edge[j].next){                if( dp[edge[j].v][0] == dp[edge[j].v][1])                 return 0;            }        }    }    return 1;}int main(){    freopen("1.txt", "r", stdin);    int ans, i;    while( scanf("%d", &n) && n){        init();        dfs(1);        flag = 1;        if( dp[1][0]== dp[1][1] )            flag= 0;        if( flag) flag= check();        printf("%d ", MAX(dp[1][0], dp[1][1]));        if( flag )printf("Yes\n");        else printf("No\n");    }    return 0;}


 

原创粉丝点击