【51nod1531】树上的博弈
来源:互联网 发布:c语言简单的冒泡排序 编辑:程序博客网 时间:2024/05/17 22:22
题目描述
有一棵n个点的有根树,他有m个叶子结点(叶子结点是那些没有孩子的结点)。边由父亲指向孩子。数字1到m被分配到每一个叶子中。每一个叶子有一个数字,并且每一个数字恰好被分配到一个叶子中。
刚开始的时候根部有一个棋子。两个玩家轮流移动棋子,每一步都会将这个棋子向他的某一个孩子移动;如果玩家不能再移动棋子了,那么游戏结束。游戏的结果就是棋子所在叶子上面的数字。游戏的先手想要这个数字最大化,而后手想要这个数字最小化。
山巴布里想要给这些叶子分配数字使得最终结果最大,而马族塔想要给这些叶子分配数字使得最终结果最小。那么当山巴布里来分配数字的时候游戏结果会是多少?马族塔分配的时候又是多少呢?山马布里和马族塔并不参加游戏,而是另外两个非常聪明的人来参加游戏。
样例解释:在这个样例中,树有三个叶子:3,4和5。如果把数字3分配给3号结点,那么第一个选手就能够让棋子到达那儿,最终结果就是3。另一方面,很明显,无论怎么分配数字,第一个选手让棋子达到最小数字是2。
Input
单组测试数据。第一行有一个整数n (1≤n≤2*10^5),表示树中结点的数目。接下来n-1行,每一行两个整数ui 和 vi (1≤ui,vi≤n) ,表示树中的边,由ui指向vi。输入保证是一棵有根树,而且根是1。
Output
输出两个整数表示最大值和最小值,以空格分开。
Input示例
样例输入151 21 32 42 5
Output示例
样例输出13 2
题解
树形dp好题。
经过思考了好几种状态之后终于把这题想出来了。
最大值和最小值是类似的,所以我们只考虑最大值就行了,我们考虑,对于先手来说,他一定要走子树最小的那一颗子树,而对于后手来说他一定走子树最多的那颗,但后手不是取max而是相加,因为它有走所有的可能啊。
所以定义f[i]表示在子树i中最终有多少个叶子权值比最后结果大,把树的深度按奇偶讨论就行了。
/* 树形dp */#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int N=200010;const int inf=1e9;int pre[N*2],last[N],other[N*2],num;int f[N],dep[N],n,chu[N];inline void add(int x,int y){num++;pre[num]=last[x];last[x]=num;other[num]=y;}void work(int x,int fa){if(chu[x]==0) f[x]=1;for(int i=last[x];i;i=pre[i]){int v=other[i];if(v!=fa){dep[v]=dep[x]+1;work(v,x);}}if(dep[x]&1){if(chu[x]!=0) f[x]=inf; for(int i=last[x];i;i=pre[i]){int v=other[i];if(v!=fa)f[x]=min(f[x],f[v]);}}else{for(int i=last[x];i;i=pre[i]){int v=other[i];if(v!=fa)f[x]+=f[v]; }}}void work1(int x,int fa){if(chu[x]==0) f[x]=1;for(int i=last[x];i;i=pre[i]){int v=other[i];if(v!=fa){dep[v]=dep[x]+1;work1(v,x);}}if(dep[x]&1){for(int i=last[x];i;i=pre[i]){int v=other[i];if(v!=fa)f[x]+=f[v];}}else{if(chu[x]!=0) f[x]=inf;for(int i=last[x];i;i=pre[i]){int v=other[i];if(v!=fa)f[x]=min(f[x],f[v]);}}}int main(){int x,y;scanf("%d",&n);for(int i=1;i<n;i++) {scanf("%d%d",&x,&y);add(x,y);add(y,x);chu[x]++;}int ans=0;for(int i=1;i<=n;i++) if(chu[i]==0) ans++;dep[1]=1;work(1,1);printf("%d ",ans-f[1]+1);dep[1]=1;memset(f,0,sizeof(f));work1(1,1);printf("%d\n",f[1]);return 0;}
阅读全文
0 0
- 【51nod1531】树上的博弈
- 树上的博弈 51Nod
- [51nod 1531]树上的博弈
- 【51Nod 1531】 树上的博弈(树形DP)
- 树上博弈
- 树上博弈
- hdu 5299 树上博弈
- 51nod 1490-多重游戏(树上博弈)
- 树上删边游戏(树上博弈)
- 图博弈,树上删边博弈
- 【树上博弈】 hdu 6105 Gameia
- HDU --- 5963 朋友 【树上博弈】
- HDU-5963 朋友(树上博弈)
- hiho #1545 : 小Hi和小Ho的对弈游戏(树上博弈)
- 【BZOJ4134】【树上博弈】【博弈论】【线段树合并】ljw和lzr的hack比赛 题解
- 多校6 Gameia-6105 树上博弈 & 染色
- 51NOD1766 树上的最远点对
- [51nod1766]树上的最远点对
- 【BZOJ2118】墨墨的等式(dijkstra)
- bzoj 1005: [HNOI2008]明明的烦恼
- 【BZOJ2287】【POJChallenge】消失之物(权限题)
- 读Zepto源码之fx_methods模块
- BZOJ1051 [HAOI2006]受欢迎的牛
- 【51nod1531】树上的博弈
- Xcode9学习笔记2
- 2017Link
- IO基础(1)-File,IO流用法
- 私有构造函数的作用
- html之解决margin-top塌陷
- 056不定积分之指数函数,三角函数,平方和\差公式
- DUBBO+SPRINGMVC+MYBATIS+EHCACHE+REDIS J2EE分布式架构
- java同步中的ReentrantLock和synchronized