HDU 5758 Explorer Bo
来源:互联网 发布:mac地址修改器win8.1 编辑:程序博客网 时间:2024/05/21 10:59
转载声明:http://blog.csdn.net/ShinFeb/article/details/52042364
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5758
题意:
给你一棵树,然后有一个人,可以在树上走,他可以选择从哪个点出发,他要遍历所以的边,每条边的权值是1,他不能回头,就是走上一次走过的边,当走不不可以走的时候,他可以传送到任意一个点,再次开始,输出的是,保证在传送次数最少的情况,能遍历所有边至少1次的最小权值和.
个人感想:
首先我对这道题的DP,看了这么多的题解我都不是特别懂,这个转载是用了贪心的做法,先做好每个边的权值,然后通过奇偶判断是否得修正权值,奇数必定得修.大牛和我说,相当于先插一个叶子点,使树变成偶数叶子节点.然后来修正路径,具体看看代码吧.题解和我的理解也不太清楚(我个人感觉..我尽力了表达了.)希望来个更好的大牛贴,来介绍清楚啊…
ps:我们不能直接把偶数子节点直接对上
这看起来好像这样子权值最小,但是!却一共跳了3次了!
题目要求是跳的次数最小的情况下权值最小
这样的才跳了2次.权值虽然大.
分析:贪心.
代码:
/* Author:GavinjouElephant * Title: * Number: * main meanning: * * * *///#define OUT#include <iostream>using namespace std;#include <cstdio>#include <cmath>#include <cstring>#include <algorithm>#include <sstream>#include <cctype>#include <vector>#include <set>#include <cstdlib>#include <map>#include <queue>//#include<initializer_list>//#include <windows.h>//#include <fstream>//#include <conio.h>#define MaxN 0x7fffffff#define MinN -0x7fffffff#define Clear(x) memset(x,0,sizeof(x))typedef long long ll;const int INF=0x3f3f3f3f;const int maxn=1e6+10;int head[maxn];int du[maxn];int ecnt;int cas;int N;int root;ll ans;ll misdis;struct Edge{ int to; int next;};Edge edge[maxn*2];int V[maxn];void init(){ misdis=0; ans=0; ecnt=0; memset(head,-1,sizeof(head)); memset(du,0,sizeof(du));}void addedge(int u,int v){ edge[ecnt].to=v; edge[ecnt].next=head[u]; head[u]=ecnt++; du[u]++;}int dfs(int s,int fa,int eid){ int son=0; for(int i=head[s];i!=-1;i=edge[i].next) { int v=edge[i].to; if(v==fa)continue; son+=dfs(v,s,(i-(i&1))); } if(eid==-1)return son; if(!son)son++; if(son&1)//如果奇数节点,只会对父边贡献1 { ans+=1; V[eid]=1; } else { ans+=2; V[eid]=2; } return son;}void tdfs(int s,int fa,int ans){ if(ans>misdis) misdis=ans; for(int i=head[s];i!=-1;i=edge[i].next) { int v=edge[i].to; if(v==fa)continue; tdfs(v,s,V[(i-(i&1))]==1?ans-1:ans+1); }}int main(){#ifdef OUT freopen("coco.txt","r",stdin); freopen("lala.txt","w",stdout);#endif scanf("%d",&cas); while(cas--) { init(); scanf("%d",&N); int x,y; for(int i=1;i<N;i++) { scanf("%d%d",&x,&y); addedge(x,y); addedge(y,x); } for(int i=1;i<=N;i++) { if(du[i]==1){root=i;break;} } ll sum=dfs(root,-1,-1)+1; if(!(sum&1)) { printf("%I64d\n",ans); continue; } tdfs(root,-1,0); ans-=misdis; cout<<misdis<<endl; printf("%I64d\n",ans); } return 0;}
0 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
- 【java】启动Eclipse报错Error when loading the SDK
- 看懂UML类图
- 使用微信支付不得不注意的坑
- eclipse 中的快捷键
- 防止出现403
- HDU 5758 Explorer Bo
- BZOJ2049 洞穴勘测 LCT
- 经典排序算法----堆与堆排序(不稳定)
- poj2377Bad Cowtractors
- 【Linux全面学习】12.修改系统启动级别
- C/C++中对象和变量的区别!!!
- KMP
- 在linux(centos)使用openssl生成https证书并配置到nginx的实现过程
- LoginFilter器