题意自己看题目吧,挺短的。

思考过程:昨天感觉一天不做题很对不起自己,于是晚上跑到实验室打开别人树形dp的博客做了上面最后一个HDU的题,也是个多校题。。一开始没有头绪了很久,因为起点不固定,所以这1e5的数据要跑的话就有很多很多转移,但是状态又不可能定义得很复杂。。然后后来就想到和叶子有关系。就这样停滞不前了很久。半夜看别人博客感觉看懂了,其实也没比没看博客前多懂多少。我只想到了肯定是一个叶子到另一个叶子然后跳一下到另一个叶子然后继续这样做。今天中午又想了很久。首先画样例是关键,学了别人的dp写法后来发现自己样例都不能过。

图一如既往的丑。

反正这个二叉树这样走是8的,然后只跳了一次,并不是网上别人说的什么(叶子+1)/2。。但是确实是叶子和叶子匹配。

我们不难发现有些边走了两次有些边走了一次。而dp的过程也是基于此。首先因为核心在于叶子,所以要以一个非叶子节点开始dfs。

我们考虑一个点u,他的某个儿子v,如果v有偶数个叶子,那么u->v这条边对答案的贡献是2,若为奇数则为1。因为一个有偶数个叶子的儿子肯定是其中某两个叶子去和v的祖先节点或者兄弟节点的叶子匹配最优(所花费的跳最少)。而奇数个时只有一个点需要这样。这个不懂的自己画一画,我也画了很久,太菜了。

如果总共有偶数个叶子,那么显然两两匹配,这就是答案。而若有奇数个叶子节点,就有一个点无法匹配,那么dfs枚举一下就好了。用dp做法就是找一条只有一个叶子的最长链。。不是特别懂。

直接放看得懂的链接吧,喜欢dp写法的自己百度,第一篇就是。

https://www.cnblogs.com/zufezzt/p/5796175.html

#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define _mp make_pair
#define db double
#define eps 1e-9
#define inf 1e9
using namespace std;
const int maxn=1e5+7;
inline ll read()
{
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int cnt;
int n,m;
int root;
int fir[maxn],nxt[maxn*2],to[maxn*2];
int du[maxn],siz[maxn];
int dp[maxn][2];
void add_e(int x,int y)
{
++cnt;nxt[cnt]=fir[x];fir[x]=cnt;to[cnt]=y;
}
void dfs1(int x,int fa)
{
dp[x][0]=0;dp[x][1]=inf;
siz[x]=0;
int ts=0;
for(int i=fir[x];i;i=nxt[i])
{
if(to[i]==fa)continue;
dfs1(to[i],x);
siz[x]+=siz[to[i]];
int d;
ts++;
if(siz[to[i]]%2==0)d=2;
else d=1;
dp[x][0]+=dp[to[i]][0]+d;
}
for(int i=fir[x];i;i=nxt[i])
{
if(to[i]==fa)continue;
if(siz[to[i]]==1&&ts>1)dp[x][1]=min(dp[x][1],dp[x][0]);
if(dp[to[i]][1]>=inf)continue;
int k=((siz[to[i]]&1)?1:-1);
dp[x][1]=min(dp[x][1],dp[x][0]-dp[to[i]][0]+dp[to[i]][1]+k);
}
if(ts==0)siz[x]=1; }
void init()
{
memset(fir,0,sizeof(fir));
cnt=0;
memset(du,0,sizeof(du));
}
int main()
{
int T;
T=read();
while(T--)
{
init();
n=read();
int p,q;
for(int i=1;i<n;i++)
{
p=read();q=read();
add_e(p,q);add_e(q,p);
du[p]++;du[q]++;
}
int ss=0;
root=0;
for(int i=1;i<=n;i++)
{
if(du[i]!=1)root=i;
else ss++;
}
dfs1(root,0);
if(n==2)cout<<"1\n";
else cout<<dp[root][ss&1]<<"\n";
}
}

  

HDU5758 Explorer Bo 思维+树形dp的更多相关文章

  1. HDU 5758 Explorer Bo(树形DP)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5758 [题目大意] 给出一棵树,每条路长度为1,允许从一个节点传送到任意一个节点,现在要求在传送次 ...

  2. HDU5758 Explorer Bo 树形dp

    我是参考这一篇写的:http://blog.csdn.net/fsss_7/article/details/52049474 一点感想:dp[i][0]代表以这个点为根的且总叶子数为偶数个叶子的答案 ...

  3. 2016多校训练3_1007(hdu5758 Explorer Bo)

    #include <functional> #include <algorithm> #include <iostream> #include <iterat ...

  4. Explorer Bo (思维 + 树链剖分)

    题意:求用最少的链覆盖所有的边用最少的总链长度. 思路:为了使得使用的链最少,我们可以知道使用的数量应该是(子叶 + 1)/ 2. 画图可知:当节点下的边数是偶数时,为了将该父节点上的边给连接上,所以 ...

  5. codeforces 456 D. A Lot of Games(字典数+博弈+思维+树形dp)

    题目链接:http://codeforces.com/contest/456/problem/D 题意:给n个字符串.进行k次游戏.每局开始,字符串为空串,然后两人轮流在末尾追加字符,保证新的字符串为 ...

  6. 洛谷AT2046 Namori(思维,基环树,树形DP)

    洛谷题目传送门 神仙思维题还是要写点东西才好. 树 每次操作把相邻且同色的点反色,直接这样思考会发现状态有很强的后效性,没办法考虑转移. 因为树是二分图,所以我们转化模型:在树的奇数层的所有点上都有一 ...

  7. Codeforces 1088E 树形dp+思维

    比赛的时候看到题意没多想就放弃了.结果最后D也没做出来,还掉分了,所以还是题目做的太少,人太菜. 回到正题: 题意:一棵树,点带权值,然后求k个子连通块,使得k个连通块内所有的点权值相加作为分子除以k ...

  8. CF482D Random Function and Tree 树形DP + 思维 + 神题

    Code: #include<bits/stdc++.h> #define ull unsigned long long #define MOD 1000000007 #define ll ...

  9. Day1:T3 bfs T4 树形DP

    T3:BFS 回看了一下Day1的T3...感觉裸裸的BFS,自己当时居然没有看出来... 同时用上升和下降两种状态bfs即可 这一题还要注意一个细节的地方,就是题目要求的是求往返的最优解 k=min ...

随机推荐

  1. mysql异常:Packet for query is too large (10240 > 1024). You can change this value

    出现这个问题的原因是:mysql的配置文件中 max_allowed_packet 设置过小,mysql根据配置文件会限制server接受的数据包大小. 还有人会说我操作的数据量明显没有超过这个值为啥 ...

  2. 将form数据转换成json对象自定义插件实现思路

  3. 动态SQL1

    If标签 动态SQL可以说是MyBatis最强大之处了,这块的应用主要有四个方面if,choose,trim和foreach,接下来先说说if. 顾名思义,if是用来判断条件的,现在假设我们有个需求, ...

  4. shell expr用法

    expr 计算整数变量值 使用方法如下: linux-zpycfm:/home/test/shell # s=+ -bash: +: command not found linux-zpycfm:/h ...

  5. Linux在shell中进入python敲方向键出现「^[[C^[[D」的解决办法

    安装yum -y install readline-devel,然后在重新编译python

  6. LODOP设置判断后执行哪个

    LODOP的语句是普通的语句,可以通过JS判断确定要执行哪个,或通过循环循环执行一些语句.如果需要执行某些打印项在哪些条件下不打印,不需要通过代码删除打印项,类似LODOP.SET_PRINT_STY ...

  7. How to flash Havoc on enchilada

    update fastboot and adb fastboot oem unlock adb debug enchilada reboot to fastboot fastboot devices ...

  8. Linux 学习 (二) 文件处理命令

    Linux达人养成计划 I 学习笔记 ls [选项] [文件或目录] -a: 显示所有文件,包括隐藏文件 -l: 显示详细信息 -d: 查看目录属性 -h: 人性化显示文件大小 -i: 显示inode ...

  9. vuejs 单文件组件.vue 文件

    vuejs 自定义了一种.vue文件,可以把html, css, js 写到一个文件中,从而实现了对一个组件的封装, 一个.vue 文件就是一个单独的组件.由于.vue文件是自定义的,浏览器不认识,所 ...

  10. AMD三代锐龙箭在弦上:如此家族堪称豪华

    AMD将于今年年中正式推出第三代Ryzen锐龙处理器,即不集成显示芯片的纯CPU产品,外界猜测可能的时间点会是5月底的台北电脑展. 虽说依然采用AM4接口,也就是X370/470老主板可无压力兼容,但 ...