您的位置:首页 > 其它

poj 3342 Party at Hali-Bula 树形dp

2012-08-20 10:39 375 查看
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: