HDU 5758 Explorer Bo
来源:互联网 发布:编程入门学什么语言 编辑:程序博客网 时间:2024/05/18 00:05
Description
Explorer Bo likes exploring mazes around the world.Now he wants to explore a new maze.
The maze has N rooms connected with N−1 roads of length 1 so that the maze looks like a tree.
Explorer Bo can transfer to a room immediately or walk along a road which is not the one he walked just now.
Because the transfer costs too much, Mr Bo will minimum the transfer using times firstly.
Mr Bo wants to walk along all the roads at least once,but he is lazy and he wants to minimum the total length he walked.
Please help him!
Initial point can be arbitrarily selected
Solution
orz ShinFeb
这个问题比赛的时候想完了70%,剩下30%死也想不到了,orz ShinFeb大爷给出了一个超神的解决方案。
比赛的时候没做出来很愧疚啊。。感觉对不起大家
这题显然dp
那个瞬移次数是可以确定的,
对于一棵以
考虑其一个子节点
如果
反之
那么可以直接dp解决。
然而如果叶子节点个数是奇数,那么有一段路径可以省掉,那咋办?
ShinFeb给了一个很好的方案
假设根节点是一个叶子节点。
我们先dp
然后考虑从根节点开始删除一段区间。
对于经过的点,只要把1反转成2,2反转成1即可。
然后求一下可以缩减的最大值即可
Code
#include<iostream>#include<string.h>#include<stdio.h>#include<algorithm>#include<vector>using namespace std;typedef long long ll;typedef vector<int> vec;#define ph push#define pb push_backconst int M=1e5+5;vec G[M];inline void Max(int &a,int b){ if(a<b)a=b;}inline void Min(int &a,int b){ if(a>b)a=b;}inline void rd(int &a){ a=0;char c; while(c=getchar(),!isdigit(c)); do a=a*10+(c^48); while(c=getchar(),isdigit(c));}ll dp[M];int sz[M];bool mark[M];void dfs(int v,int f){ bool flag=0; for(int i=0;i<G[v].size();++i){ int to=G[v][i]; if(to==f)continue; dfs(to,v); if(sz[to]&1)++dp[v]; else dp[v]+=2; dp[v]+=dp[to]; sz[v]+=sz[to]; flag=1; } if(!flag)mark[v]=1,sz[v]=1;}int Mx=0;inline void rdfs(int v,int f,int dlt){ Max(Mx,dlt); for(int i=0;i<G[v].size();++i){ int to=G[v][i]; if(to^f)rdfs(to,v,dlt+(sz[to]&1?-1:1)); }}inline void gao(){ int n;cin>>n; for(int i=1;i<=n;++i)G[i].clear(); memset(dp,0,sizeof(dp)); memset(sz,0,sizeof(sz)); Mx=0; for(int i=1,a,b;i<n;++i){ rd(a),rd(b); G[a].pb(b),G[b].pb(a); } int s; for(int i=1;i<=n;++i) if(G[i].size()==1)s=i; dfs(s,s); rdfs(s,s,0); ++sz[s]; if(sz[s]&1)cout<<dp[s]-Mx<<endl; else cout<<dp[s]<<endl;}int main(){ int _; for(cin>>_;_--;)gao(); return 0;}
- HDU 5758 Explorer Bo
- HDU 5758 Explorer Bo
- HDU 5758 Explorer Bo
- HDU 5758 Explorer Bo (树形DP)
- 【HDU 5758】Explorer Bo(树型dp)
- HDU 5758 Explorer Bo(树形DP)
- 2016 暑假多校训练 第三场 1007 Explorer Bo HDU 5758
- 2016MUTC3-1007 Explorer Bo
- HDU-4634-Swipe Bo
- hdu 4634 Swipe Bo
- HDU 4634 Swipe Bo
- hdu 4634 Swipe Bo
- hdu 5753 Permutation Bo
- hdu 5752 Sqrt Bo
- hdu 5762 Teacher Bo
- HDU 5752 Sqrt Bo
- HDU 5753 Permutation Bo
- HDU 5761 Rower Bo
- 持续集成框架,自动部署服务搭建jenkins+maven+svn(git)+shell
- Java-面向对象基础知识
- iOS --- 关于KVC使用的一些小技巧
- 单例与反射
- Android Studio JNI
- HDU 5758 Explorer Bo
- 深入理解Java反射机制
- 剑指offer面试题40:数组中只出现一次的数字
- C++11的push_back, move, rvalue, emplace_back
- jq方法each、forEach和map的区别
- 深度学习在搜索和推荐领域的应用
- WINDOWS无法搜索新更新错误代码80070422
- 初学java细节问题
- 在Windows系统上以C++打印出当前活动用户的环境变量