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

思考过程:昨天感觉一天不做题很对不起自己,于是晚上跑到实验室打开别人树形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. centos 7 aufs

    Docker storage drivers | Docker Documentationhttps://docs.docker.com/storage/storagedriver/select-st ...

  2. C\C++学习笔记 1

    C++记录1 C的头文件为math.h C++的为 cmath using编译指令 namespace 区分不同产品的函数.Mics::cout Linux::cout cout << 即 ...

  3. Day 6-2简单的socket通信

    什么是socket? Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面 ...

  4. java学习之—递归

    /** * 递归 * Create by Administrator * 2018/6/20 0020 * 上午 9:41 **/ public class TriangleApp { static ...

  5. ServiceLoader详解

    系统中用到了ServiceLoader,查了一下: ServiceLoader与ClassLoader是Java中2个即相互区别又相互联系的加载器.JVM利用ClassLoader将类载入内存,这是一 ...

  6. 用织梦建站如何去掉a这个目录,还有内容页的a

    1.另外建一个站点,将物理路径直接指向a即可. 2.去掉文章页生成的带a的路径: 只需要这一句话:  function='str_replace("/a","" ...

  7. qtp 自动化测试桌面程序-点滴1(录制设置、共用文件)

    1 automation-record and run settings--设置录制程序 2 将function/repository 放于单独于test的文件夹中-方便多个test使用同一个仓库.函 ...

  8. SpringBoot之整合Mybatis范例

    依赖包: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http:/ ...

  9. qt 在窗口上画框

    在窗口w上面画个黄色的框:在窗口上添加一个label,然后在label上画框 QLabel label(&w); label.setScaledContents(true); QPixmap ...

  10. Lisp小程序,大作用,不该放弃!

    从听说autolisp到现在已经20年了, 学了一点点, 可惜中间没能坚持下来, 放弃了!     今天在画图, 图纸是从revit转成dwg的, 其中有些文本的朝向是错误的, 如果手工旋转很是费事, ...