您的位置:首页 > 其它

UVA1220Party at Hali-Bula(树的最大独立集 + 唯一性判断)

2016-02-02 17:44 411 查看
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=105116#problem/H

紫书P282

员工和直属老板只能选一个,最多选多少人

思路:d(u,0)表示以U为根的子树,不选u点,则子节点可选可不选,f(u,0)表示不选u的唯一性 (1表示唯一,0,表示不唯一)

d(u,1)以u为根的子树,选择u点,f(u,1)表示选择u的唯一性

转移方程:d(u,0) = sum{ max( d(v,0), d(v,1) ) },v是子节点,当d(v,0) == d(v,1) ,不唯一,或者选择的那个不唯一,则f(u,0)不唯一

d(u,1) = sum{ d(v,0) }, 当f(v,0)有一个不唯一,则不唯一

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <map>
using namespace std;
const int MAX = 210;
vector <int> son[MAX];
map<string, int> name;
int d[MAX][2],f[MAX][2];
void DP(int u)
{
if(son[u].size() == 0)
{
d[u][1] = f[u][1] = 1;
d[u][0] = 0;
f[u][0] = 1;
return;
}
int c = (int) son[u].size();
for(int i = 0; i < c; i++)
{
DP(son[u][i]);
}
int sum = 0,flag = 0;
for(int i = 0; i < c; i++)
{
sum += d[ son[u][i] ][0];
if(f[ son[u][i] ][0] == 0)
flag = 1;
}
if(flag)
f[u][1] = 0;
else
f[u][1] = 1;
d[u][1] = max(d[u][1], sum + 1);
sum = 0,flag = 0;
for(int i = 0; i < c; i++)
{
if(d[ son[u][i] ][1] > d[ son[u][i] ][0])
{
sum += d[ son[u][i] ][1] ;
if(f[ son[u][i] ][1] == 0)
flag = 1;
}
else if(d[ son[u][i] ][1] < d[ son[u][i] ][0])
{
sum += d[ son[u][i] ][0];
if(f[ son[u][i] ][0] == 0)
flag = 1;
}
else
{
sum += d[ son[u][i] ][0];
flag = 1;
}
}
if(flag)
f[u][0] = 0;
else
f[u][0] = 1;
d[u][0] = max(d[u][0], sum);
}
int main()
{
int n,m;
char worker[110],boss[110];
while(scanf("%d", &n) != EOF && n)
{
for(int i = 0; i < MAX; i++)
son[i].clear();
name.clear();
memset(d, 0, sizeof(d));
memset(f, 0, sizeof(f));
m = 0;
scanf("%s", boss);
name[boss] = m++;
for(int i = 1; i < n; i++)
{
scanf("%s%s",worker,boss);
if(name.count(worker) == 0)  //注意输入的处理
name[worker] = m++;
if(name.count(boss) == 0)
name[boss] = m++;
son[ name[boss] ].push_back( name[worker] );
}
DP(0);
if(d[0][0] > d[0][1])
{
printf("%d ", d[0][0]);
if(f[0][0])
printf("Yes\n");
else
printf("No\n");
}
else if(d[0][0] < d[0][1])
{
printf("%d ", d[0][1]);
if(f[0][1])
printf("Yes\n");
else
printf("No\n");
}
else
{
printf("%d ", d[0][0]);
printf("No\n");
}
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: