hdu5758 2016 Multi-University Training Contest 3 Explorer Bo 解题报告
来源:互联网 发布:怎么找淘宝女主播 编辑:程序博客网 时间:2024/05/16 10:22
感觉最近都没状态不知道为什么。。。。一道不难的题不会做,看了题解发现自己好蠢。。。。
题意:给一颗n个节点的树,问你用最少的链覆盖这棵树上所有的边(可以重复覆盖),链的长度和最小为多少
链的长度=覆盖的边的数量
题解:
树形DP
首先,如果要覆盖,最少需要(n+1)/2条链,链的两端肯定是2个叶子节点,如果叶子节点数是奇数,那么有一条链由一个叶子向上覆盖他父亲连向他的边就停止
那么,定义f[x]为以x为根的子树内用最少的链覆盖,链的最小长度和,
首先一棵子树里的叶子肯定先两两匹配,再考虑和子树根的父亲的连边
如果他的一个孩子y的子树内叶子节点数为奇数,就一定有1条链连上来(为了覆盖x和y的边),对f[x]贡献f[y]+1
如果他的一个孩子y的子树内叶子节点数为偶数,就一定有2条链连上来(首先为了覆盖x和y的边,至少要有一条链,那这个叶子连上来,剩余的原来和他匹配的点没有点匹配,故也连一条链上来),对f[x]贡献f[y]+2
最后,求完整棵树的f后,对整棵树考虑,
如果整棵树的叶子节点数是偶数,可以直接输出根的f值
如果是奇数,那么会有一条链叶子连上来的链没有叶子匹配,事实上这条链也不用连上来,只要连向这个叶子的父亲即可,所以对于这种情况,我们要撤销一条链,考虑撤销一条链的影响,
从这个叶子走上去,如果x到y这条边之前只被这一条链覆盖,撤消后无边覆盖,就要像上面的情况一样,走两条边上去,答案+1,
如果这条边之前被覆盖了2次,那么撤销了没有影响,答案-1,遍历整棵树找到使答案最小的就行了
注意一个地方,就是如果你选的根是一个叶子节点,那整棵树的叶子节点数要+1,根是不能例外的
code:
#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<ctime>#include<cmath>#include<string>#include<bitset>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define LL long longusing namespace std;const int maxn = 110000;struct edge{int y,next;}a[maxn<<1]; int len,first[maxn];LL f[maxn];int siz[maxn];int n,m;void ins( int x,int y ){len++;a[len].y = y;a[len].next = first[x]; first[x] = len;}void dfs( int x,int fa ){bool flag = true;siz[x] = 0; f[x] = 0;for( int k=first[x];k;k=a[k].next ){int y = a[k].y;if( y != fa ){dfs( y,x );flag = false;siz[x] += siz[y];if( siz[y]&1 ) f[x] += f[y]+1;else f[x] += f[y]+2;}}if( flag ) siz[x] = 1;}LL fm( int x,int fa ){LL mx = 0;for( int k=first[x];k;k=a[k].next ){int y = a[k].y;if( y != fa ){LL temp = fm( y,x );temp += (siz[y]&1)?-1:1;if( temp > mx ) mx = temp;}}return mx;}int main(){int t;scanf("%d",&t);while( t-- ){memset( first,0,sizeof first ); len = 0;int x,y;scanf("%d",&n);for( int i=1;i<n;i++ ){scanf("%d%d",&x,&y);ins( x,y ); ins( y,x );}dfs( 1,0 );if( a[first[1]].next == 0 ) siz[1]++;if( siz[1]&1 )f[1] -= fm( 1,0 );printf("%lld\n",f[1]);}return 0;}
0 0
- hdu5758 2016 Multi-University Training Contest 3 Explorer Bo 解题报告
- hdu5752 2016 Multi-University Training Contest 3 Sqrt Bo 解题报告
- hdu5753 2016 Multi-University Training Contest 3 Permutation Bo 解题报告
- hdu5754 2016 Multi-University Training Contest 3 Life Winner Bo 解题报告
- hdu5755 2016 Multi-University Training Contest 3 Gambler Bo 解题报告
- hdu5756 2016 Multi-University Training Contest 3 Boss Bo 解题报告
- hdu 5759 2016 Multi-University Training Contest 3 Gardener Bo 解题报告
- 2016 Multi-University Training Contest 3----解题报告
- 2016 Multi-University Training Contest 3 解题报告
- 【解题报告】2016 Multi-University Training Contest 3
- 2014 Multi-University Training Contest 解题报告
- 2016 Multi-University Training Contest 1----解题报告
- 2016 Multi-University Training Contest 2----解题报告
- 2016 Multi-University Training Contest 4 解题报告
- 2016 Multi-University Training Contest 5 解题报告
- 2016 Multi-University Training Contest 6 解题报告
- 【解题报告】2016 Multi-University Training Contest 4
- 2015 Multi-University Training Contest 3 解题报告
- Rajawali是一个用于Android应用的3D引擎
- 网易2017校园招聘笔试题:优雅的点
- 【Day3】如何防止表单重复提交?
- 安卓开发之ScrollView嵌套ListView的一些问题和解决
- React实战-通过ReactRouter-example分析Router用法
- hdu5758 2016 Multi-University Training Contest 3 Explorer Bo 解题报告
- x265源码分析:main函数及CLIOptions结构体解释
- 【华为OJ】查找兄弟单词(未通过)
- NOIP提高组 【JZOJ4778】数列编辑器
- 学习日记20160915
- maze
- HTML5 <canvas> 参考手册
- Hust oj 1949 寻找宝藏(BFS)
- 探讨C++中对象的“浅拷贝”与“深拷贝”