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
原创粉丝点击