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)有一个不唯一,则不唯一
View Code
紫书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
相关文章推荐
- 我写出了一个看起来有点高大上的页面!!!
- 8.Java 加解密技术系列之 PBE
- 神经网络
- 河南第四届ACM省赛(序号互换)
- Android中Gson解析详解json3
- 不要总说自己是加班狗,狗从来不加班
- LightOJ--1152--Hiding Gold(二分图奇偶建图)(好题)
- 关于 tomcat 集群中 session 共享的三种方法
- 关于Android的addview
- POJ 1159 Palindrome
- Mysql语句
- LightOJ--1152--Hiding Gold(二分图奇偶建图)(好题)
- 对象排序,实现comparable接口
- Web 研发模式演变
- Hadoop运维笔记 之 Namenode异常停止后无法正常启动
- 使用正则实现字符去重及多行去重
- js cookies存取删操作实例
- HashMap归档-超越昨天的自己系列
- jupyter notebook + pyspark 环境搭建
- 指针注意事项