HDU5758 Explorer Bo 思维+树形dp
题意自己看题目吧,挺短的。
思考过程:昨天感觉一天不做题很对不起自己,于是晚上跑到实验室打开别人树形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的更多相关文章
- HDU 5758 Explorer Bo(树形DP)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5758 [题目大意] 给出一棵树,每条路长度为1,允许从一个节点传送到任意一个节点,现在要求在传送次 ...
- HDU5758 Explorer Bo 树形dp
我是参考这一篇写的:http://blog.csdn.net/fsss_7/article/details/52049474 一点感想:dp[i][0]代表以这个点为根的且总叶子数为偶数个叶子的答案 ...
- 2016多校训练3_1007(hdu5758 Explorer Bo)
#include <functional> #include <algorithm> #include <iostream> #include <iterat ...
- Explorer Bo (思维 + 树链剖分)
题意:求用最少的链覆盖所有的边用最少的总链长度. 思路:为了使得使用的链最少,我们可以知道使用的数量应该是(子叶 + 1)/ 2. 画图可知:当节点下的边数是偶数时,为了将该父节点上的边给连接上,所以 ...
- codeforces 456 D. A Lot of Games(字典数+博弈+思维+树形dp)
题目链接:http://codeforces.com/contest/456/problem/D 题意:给n个字符串.进行k次游戏.每局开始,字符串为空串,然后两人轮流在末尾追加字符,保证新的字符串为 ...
- 洛谷AT2046 Namori(思维,基环树,树形DP)
洛谷题目传送门 神仙思维题还是要写点东西才好. 树 每次操作把相邻且同色的点反色,直接这样思考会发现状态有很强的后效性,没办法考虑转移. 因为树是二分图,所以我们转化模型:在树的奇数层的所有点上都有一 ...
- Codeforces 1088E 树形dp+思维
比赛的时候看到题意没多想就放弃了.结果最后D也没做出来,还掉分了,所以还是题目做的太少,人太菜. 回到正题: 题意:一棵树,点带权值,然后求k个子连通块,使得k个连通块内所有的点权值相加作为分子除以k ...
- CF482D Random Function and Tree 树形DP + 思维 + 神题
Code: #include<bits/stdc++.h> #define ull unsigned long long #define MOD 1000000007 #define ll ...
- Day1:T3 bfs T4 树形DP
T3:BFS 回看了一下Day1的T3...感觉裸裸的BFS,自己当时居然没有看出来... 同时用上升和下降两种状态bfs即可 这一题还要注意一个细节的地方,就是题目要求的是求往返的最优解 k=min ...
随机推荐
- react 路由 react-router-dom
import React from 'react'; import DataList from './data' import Tr from './Tr' // import One from '. ...
- HDU 4913 Least common multiple
题目:Least common multiple 链接:http://acm.hdu.edu.cn/showproblem.php?pid=4913 题意:有一个集合s,包含x1,x2,...,xn, ...
- mybatis事务管理机制详解
1.mybatis事务的配置和使用 mybatis事务有两种使用方式: (a):使用JDBC的事务管理机制:即使用java.Sql.Connection对象完成对事务的提交,回滚和关闭操作. (b): ...
- flutter image_picker使用照相机
dependencies: image_picker: ^0.4.12+1 最新的^0.5+9编译无法通过 import 'dart:io'; import 'dart:async'; import ...
- AspectJ用注解替换xml配置
AspectJ基于注解的使用 AspectJ简介 AspectJ是一个基于Java语言的AOP框架,一般 其主要用途:自定义开发 一般情况下spring自动生成代理,要配置aop, 首先确定目标类,a ...
- mac 电脑 打开隐藏文件
command +shift +. 第一次是打开,第二次是关闭
- Delphi 限制Edit输入 多个例子
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char); begin if not (key in [ '.',#8]) then ...
- ArrayList 初学小结!
package good.com; import java.util.ArrayList;//导入 ArrayList 包 调用动态数组! public class ArrayListList { / ...
- codeforces534B
Covered Path CodeForces - 534B The on-board computer on Polycarp's car measured that the car speed a ...
- form-layui
html <div id="formData"> <form class="layui-form formBtn" style="m ...