题意:

有一棵树,选出尽可能多的节点是的两两节点不相邻,即每个节点和他的子节点只能选一个。求符合方案的最大节点数,并最优方案判断是否唯一。

分析:

d(u, 0)表示以u为根的子树中,不选u节点能得到的最大人数,f(u, 0)表示方案是否唯一。

d(u, 1)表示选u节点能得到的最大人数,同理,f(u, 1)表示方案是否唯一。

状态的转移:

    • d(u, 1)的计算:因为选了u节点,所以u的子节点都不能选。d(u, 1) = sum{ d(v, 0) | v是u的子节点 }
    • f(u, 1)的计算:当且仅当f(v, 0) == 1时,f(u, 1)才是1
    • d(u, 0)的计算:因为没有选u节点,所以对于每个子节点v可选可不选。d(u, 0) = sum{ max(d(v, 0),  d(v, 1)) }
    • f(u, 0)的计算:方案不唯一有两种情况,某个d(v, 1) == d(v, 0) 或者 对应取到max方案的f为1

这里用了C++中的map,将字符串与编号对应起来,编写代码比较方便。

 //#define LOCAL
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <map>
#include <vector>
#include <iostream>
using namespace std; const int maxn = ;
vector<int> sons[maxn];
map<string, int> dict;
int cnt, d[maxn][], f[maxn][]; int ID(const string& s)
{
if(!dict.count(s)) dict[s] = cnt++;
return dict[s];
} int dp(int u, int k) {
f[u][k] = ;
d[u][k] = k;
for(int i = ; i < sons[u].size(); i++) {
int v = sons[u][i];
if(k == ) { //选节点u
d[u][] += dp(v, );
if(!f[v][]) f[u][] = ; //如果子节点v不唯一,则父节点u也不唯一
} else {
d[u][] += max(dp(v, ), dp(v, ));
if(d[v][] == d[v][]) f[u][k] = ;
else if(d[v][] > d[v][] && !f[v][]) f[u][k] = ;
else if(d[v][] > d[v][] && !f[v][]) f[u][k] = ;
}
}
return d[u][k];
} int main(void)
{
#ifdef LOCAL
freopen("1220in.txt", "r", stdin);
#endif int n;
string s, s2;
while(cin >> n >> s)
{
getchar();
cnt = ;
dict.clear();
for(int i = ; i <= n; ++i) sons[i].clear(); //cin >> s;
ID(s);
for(int i = ; i < n; ++i)
{
cin >> s >> s2;
sons[ID(s2)].push_back(ID(s));
}
printf("%d ", max(dp(, ), dp(, )) );
bool unique = false;
if(d[][] > d[][] && f[][]) unique = true;
if(d[][] > d[][] && f[][]) unique = true;
printf("%s\n", unique ? "Yes" : "No");
} return ;
}

代码君

UVa 1220 (树的最大独立集) Party at Hali-Bula的更多相关文章

  1. UVa 1220 Hali-Bula的晚会(树的最大独立集)

    https://vjudge.net/problem/UVA-1220 题意: 公司里有n个人形成一个树状结构,即除了老板以外每个员工都有唯一的直属上司.要求选尽量多的人,但不能同时选择一个人和他的直 ...

  2. POJ 3342 Party at Hali-Bula / HDU 2412 Party at Hali-Bula / UVAlive 3794 Party at Hali-Bula / UVA 1220 Party at Hali-Bula(树型动态规划)

    POJ 3342 Party at Hali-Bula / HDU 2412 Party at Hali-Bula / UVAlive 3794 Party at Hali-Bula / UVA 12 ...

  3. UVa 1220 - Party at Hali-Bula(树形DP)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  4. POJ 2342 树的最大独立集

    题意:在树的最大独立集的基础上,加上权值.求最大. 分析: 采用刷表的方式写记忆化,考虑一个点选和不选,返回方式pair 型. 首先,无根树转有根树,dp(root). 注意的是:u不选,那么他的子节 ...

  5. POJ 3342 Party at Hali-Bula (树形dp 树的最大独立集 判多解 好题)

    Party at Hali-Bula Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 5660   Accepted: 202 ...

  6. 求树的最大独立集,最小点覆盖,最小支配集 贪心and树形dp

    目录 求树的最大独立集,最小点覆盖,最小支配集 三个定义 贪心解法 树形DP解法 (有任何问题欢迎留言或私聊&&欢迎交流讨论哦 求树的最大独立集,最小点覆盖,最小支配集 三个定义 最大 ...

  7. HDU - 1520 Anniversary party (树的最大独立集)

    Time limit :1000 ms :Memory limit :32768 kB: OS :Windows There is going to be a party to celebrate t ...

  8. UVA - 1220 Party at Hali-Bula 树的最大独立集

    题意:  给定n个人,存在上下级关系,每个人只有一个上级,求最大独立集.并判断最大独立集是否唯一 思路:d[i][0]表示以i为根的子树中,不选择第i个节点的最大独立集,f[i][0]表示以i为根的子 ...

  9. UVa 1220 Party at Hali-Bula (树形DP,最大独立集)

    题意:公司有 n 个人形成一个树形结构,除了老板都有唯一的一个直系上司,要求选尽量多的人,但不能同时选一人上和他的直系上司,问最多能选多少人,并且是不是唯一的方案. 析:这个题几乎就是树的最大的独立集 ...

随机推荐

  1. 邻结矩阵的建立和 BFS,DFS;;

    邻结矩阵比较简单,, 它的BFS,DFS, 两种遍历也比较简单,一个用队列, 一个用数组即可!!!但是邻接矩阵极其浪费空间,尤其是当它是一个稀疏矩阵的时候!!!-------------------- ...

  2. Jquery 判断浏览器类型

    $(function() { //FireFox2及以上 if ($.browser.MozillaSideBar && $.browser.version >= "1 ...

  3. html——a标签添加点击事件,火狐浏览器直接显示0

    一.问题描述 给一个a标签添加了点击事件,页面直接给了0如下图 二.问题解决 后台调试模式下,发现也进了后台方法,也返回了页面. 于是想到先把页面里大部分内容去掉,去掉所有js,查看是否是部分代码有问 ...

  4. NYOJ-456 邮票分你一半 AC 分类: NYOJ 2014-01-02 14:33 152人阅读 评论(0) 收藏

    #include<stdio.h> #define max(x,y) x>y?x:y int main(){ int n,x,y; scanf("%d",& ...

  5. Webbrowser 取消下载提示框

    在使用Webbrowser抓取网页信息时,碰到需要下载文件,这时需要用户介入操作,如何避免: 首先引进 [DllImport("urlmon.dll", CharSet = Cha ...

  6. java 正则匹配空格字符串 正则表达式截取字符串

    java 正则匹配空格字符串 正则表达式截取字符串 需求:从一堆sql中取出某些特定字符串: 比如配置的sql语句为:"company_code = @cc and project_id = ...

  7. 有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。

    先写我的思路,没有用指针的做法.如果你用的是VC,把第六行去掉. #include<stdio.h> #include<stdlib.h> int main() { setvb ...

  8. 去除List集合中的重复对象,Map遍历代码

    /*** * 去除List<PartsInfoDTO>列表中的重复对象 ~!! * @param list * @return */ public static List<Parts ...

  9. Chp18: Hard

    18.1 Write a function that adds two numbers. You should not use + or any arithmetic operators. Solut ...

  10. javascript加速运动

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...