【uva】1220 Party at Hali-Bula
2016-03-30 12:31
381 查看
1. 题目描述
公司里有$n, n \in [1, 200]$个人,他们间的关系构成树状结构。除老板外,每个员工都有唯一一个直属上司,要求从中选择尽量多的人,但是不能同时选择员工和他的直属上司,问最多能选多少人,以及可行解是否是唯一的?
2. 基本思路
这显然又是一个树形DP的题目,经典模型——树的最大独立集。《算法竞赛入门经典》中的典型例题,唯一稍微不同的是需要判断可行解是否唯一。因此,先分析状态:
(1) $dp[u][0]$表示不选$u$的最大人数,$f[u][0]$表示当前选择是否唯一,此时可以选择、也可以不选择$u$的下属;
(2) $dp[u][1]$表示选择$u$的最大人数,$f[u][1]$表示当前选择是否唯一,此时一定不能选择$u$的下属;
可以很容易推导状态转移方程:
\begin{align}
dp[u][0] &= \sum \max (dp[v][0], dp[v][1]) \\
f[u][0] &= \bigwedge \Big( (dp[v][0] \neq dp[v][1]) \wedge f[v][dp[v][0] < dp[v][1]] \Big) \\
dp[u][1] &= \sum dp[v][0] \\
f[u][1] &= \bigwedge f[v][0]
\end{align}
可以使用刷表法进行实现这个DP,经典的树形DP模型。
3. 代码
公司里有$n, n \in [1, 200]$个人,他们间的关系构成树状结构。除老板外,每个员工都有唯一一个直属上司,要求从中选择尽量多的人,但是不能同时选择员工和他的直属上司,问最多能选多少人,以及可行解是否是唯一的?
2. 基本思路
这显然又是一个树形DP的题目,经典模型——树的最大独立集。《算法竞赛入门经典》中的典型例题,唯一稍微不同的是需要判断可行解是否唯一。因此,先分析状态:
(1) $dp[u][0]$表示不选$u$的最大人数,$f[u][0]$表示当前选择是否唯一,此时可以选择、也可以不选择$u$的下属;
(2) $dp[u][1]$表示选择$u$的最大人数,$f[u][1]$表示当前选择是否唯一,此时一定不能选择$u$的下属;
可以很容易推导状态转移方程:
\begin{align}
dp[u][0] &= \sum \max (dp[v][0], dp[v][1]) \\
f[u][0] &= \bigwedge \Big( (dp[v][0] \neq dp[v][1]) \wedge f[v][dp[v][0] < dp[v][1]] \Big) \\
dp[u][1] &= \sum dp[v][0] \\
f[u][1] &= \bigwedge f[v][0]
\end{align}
可以使用刷表法进行实现这个DP,经典的树形DP模型。
3. 代码
/* uva1220 */ #include <iostream> #include <sstream> #include <string> #include <map> #include <queue> #include <set> #include <stack> #include <vector> #include <deque> #include <bitset> #include <algorithm> #include <cstdio> #include <cmath> #include <ctime> #include <cstring> #include <climits> #include <cctype> #include <cassert> #include <functional> #include <iterator> #include <iomanip> #include <tr1/unordered_map> using namespace std; //#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int> #define stpii set<pair<int, int> > #define mpii map<int,int> #define vi vector<int> #define pii pair<int,int> #define vpii vector<pair<int,int> > #define rep(i, a, n) for (int i=a;i<n;++i) #define per(i, a, n) for (int i=n-1;i>=a;--i) #define clr clear #define pb push_back #define mp make_pair #define fir first #define sec second #define all(x) (x).begin(),(x).end() #define SZ(x) ((int)(x).size()) #define lson l, mid, rt<<1 #define rson mid+1, r, rt<<1|1 #define INF 0x3f3f3f3f #define mset(a, val) memset(a, (val), sizeof(a)) const int maxn = 205; vi E[maxn]; int fa[maxn]; int dp[maxn][2]; bool f[maxn][2]; int n; int pid; map<string,int> tb; map<string,int>::iterator iter; void init() { rep(i, 0, n+1) { E[i].clr(); fa[i] = 0; } tb.clr(); pid = 1; memset(dp, 0, sizeof(dp)); memset(f, true, sizeof(f)); } inline void addEdge(int u, int v) { fa[v] = u; E[u].pb(v); } inline int findId(const string& s) { int ret; iter = tb.find(s); if (iter == tb.end()) { tb[s] = ret = pid++; } else { ret = iter->sec; } return ret; } void dfs(int u) { int sz = SZ(E[u]), v; dp[u][1] = 1; rep(i, 0, sz) { v = E[u][i]; dfs(v); } // choose fa[u] choose u dp[fa[u]][1] += dp[u][0]; f[fa[u]][1] &= f[u][0]; // not choose fa[u], choose or not u dp[fa[u]][0] += max(dp[u][0], dp[u][1]); f[fa[u]][0] &= (dp[u][0]!=dp[u][1]) & (f[u][dp[u][0]<dp[u][1]]); } void solve() { dfs(1); if (dp[1][0] > dp[1][1]) printf("%d %s\n", dp[1][0], f[1][0]?"Yes":"No"); else if (dp[1][0] < dp[1][1]) printf("%d %s\n", dp[1][1], f[1][1]?"Yes":"No"); else printf("%d No\n", dp[1][1]); } int main() { ios::sync_with_stdio(false); #ifndef ONLINE_JUDGE freopen("data.in", "r", stdin); freopen("data.out", "w", stdout); #endif string su, sv; int uid, vid; while (cin>>n && n) { init(); cin >> su; findId(su); rep(i, 1, n) { cin >> sv >> su; uid = findId(su); vid = findId(sv); addEdge(uid, vid); } solve(); } #ifndef ONLINE_JUDGE printf("time = %ldms.\n", clock()); #endif return 0; }
相关文章推荐
- LeetCode 324. Wiggle Sort II
- 剑指offer相关题目:求链表的中间结点
- Linux下mysql数据库的导入导出操作
- XML约束
- Java集合源码之路-List分析(一)续
- jQuery源代码学习笔记:构造jQuery对象
- Sublime Text3 左侧文件树里面中文显示成方块(乱码)的解决办法
- Opencv之矩阵的掩码操作
- App加密那点事&浅浅析加密原理
- 【强烈推荐】XCODE的插件之王
- svn的简单使用
- http请求和json解析的截取字符串
- hibernate注解详解
- OSX cordova+Ionic的安装配置
- Java中如何将以byte数组给出的数据转换为double数组形式
- Android中获取各种服务是哪里来的
- 7个步骤掌握使用python进行机器学习
- Scalaz(37)- Free :实践-DB Transaction free style
- redmine 安装
- http请求和json解析