题目:

分析:

  首先明确我们是要求 min(dist[C][A],dist[C][B])+dist[A][B].

  我们把C当成树根,第一我们可以发现min里面取dist[C][A]或者dist[C][B]其实是一个意思(因为可以交换)。

  接着可以发现dist[A][B]实际上是这棵树的直径。如果不是,那么答案一定不是最优的。我们可以这样去想:

    如果dist[A][B]不是直径,那么一定有dist[C][A']使得比dist[C][A]更优,而且A'一定是直径的一个端点:-)。加号的前面和后面都不是最优的,那么答案也不是最优的。

  所以我们可以先处理出树的直径,接着枚举点C使得它到两个端点的距离的最小值最大。

  时间复杂度O(n),空间复杂度O(n)。  

代码:

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<vector>
  6. using namespace std;
  7.  
  8. typedef long long ll;
  9.  
  10. struct edge{
  11. ll to,w;
  12. };
  13.  
  14. const ll maxn = ;
  15.  
  16. ll n,m;
  17. vector <edge> g[maxn];
  18. ll arr[maxn],dep[maxn];
  19.  
  20. void dfs(int now,ll data){
  21. arr[now] = ;
  22. dep[now] = min(dep[now],data);
  23. for(int i=;i<g[now].size();i++){
  24. if(arr[g[now][i].to]) continue;
  25. dfs(g[now][i].to,g[now][i].w+data);
  26. }
  27. arr[now] = ;
  28. }
  29.  
  30. int get_max(){
  31. dep[] = ;
  32. int maxx = ;
  33. for(int i=;i<=n;i++){
  34. if(dep[maxx] < dep[i]) maxx = i;
  35. }
  36. return maxx;
  37. }
  38.  
  39. void read(){
  40. scanf("%lld%lld",&n,&m);
  41. for(ll i=;i<=m;i++){
  42. ll x,y,c; scanf("%lld%lld%lld",&x,&y,&c);
  43. g[x].push_back((edge){y,c});
  44. g[y].push_back((edge){x,c});
  45. }
  46. }
  47.  
  48. void work(){
  49. memset(dep,/,sizeof(dep));
  50. dfs(,);//get the farthest point in tree
  51. ll ans=,t1 = get_max();
  52. memset(dep,/,sizeof(dep));
  53. dfs(t1,);//another point
  54. ll t2 = get_max();
  55. ans += dep[t2];//zhijing
  56. dfs(t2,);
  57. ll maxx = ;
  58. for(int i=;i<=n;i++)
  59. maxx = max(maxx,dep[i]);
  60. ans += maxx; // farthest dian for zhijing
  61. printf("%lld",ans);
  62. }
  63.  
  64. int main(){
  65. read();
  66. work();
  67. return ;
  68. }

BZOJ1509 [NOI2003]逃学的小孩 树型DP的更多相关文章

  1. BZOJ 1509 逃学的小孩 - 树型dp

    传送门 题目大意: 在一棵树中, 每条边都有一个长度值, 现要求在树中选择 3 个点 X.Y. Z , 满足 X 到 Y 的距离不大于 X 到 Z 的距离, 且 X 到 Y 的距离与 Y 到 Z 的距 ...

  2. BZOJ1509: [NOI2003]逃学的小孩(树的直径)

    Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1126  Solved: 567[Submit][Status][Discuss] Description ...

  3. BZOJ1509: [NOI2003]逃学的小孩 (树形DP)

    题意:给一棵树 选三个点A,B,C 求A到B的再从B到C的距离最大值 需要满足AB的距离小于AC的距离 题解:首先树上的最大距离就想到了直径 但是被样例误导了TAT BC两点构成了直径 我一开始以为A ...

  4. BZOJ1509 NOI2003 逃学的小孩

    Description: Input: 第一行是两个整数N(3  N  200000)和M,分别表示居住点总数和街道总数.以下M行,每行给出一条街道的信息.第i+1行包含整数Ui.Vi.Ti(1 ...

  5. BZOJ 1509: [NOI2003]逃学的小孩( 树形dp )

    树形dp求出某个点的最长3条链a,b,c(a>=b>=c), 然后以这个点为交点的最优解一定是a+2b+c.好像还有一种做法是求出树的直径然后乱搞... ----------------- ...

  6. 【BZOJ1509】[NOI2003]逃学的小孩 直径

    [BZOJ1509][NOI2003]逃学的小孩 Description Input 第一行是两个整数N(3  N  200000)和M,分别表示居住点总数和街道总数.以下M行,每行给出一条街道的 ...

  7. [NOI2003]逃学的小孩(树的直径)

    [NOI2003]逃学的小孩 题目描述 Chris家的电话铃响起了,里面传出了Chris的老师焦急的声音:"喂,是Chris的家长吗?你们的孩子又没来上课,不想参加考试了吗?"一听 ...

  8. POJ3659 Cell Phone Network(树上最小支配集:树型DP)

    题目求一棵树的最小支配数. 支配集,即把图的点分成两个集合,所有非支配集内的点都和支配集内的某一点相邻. 听说即使是二分图,最小支配集的求解也是还没多项式算法的.而树上求最小支配集树型DP就OK了. ...

  9. POJ 3342 - Party at Hali-Bula 树型DP+最优解唯一性判断

    好久没写树型dp了...以前都是先找到叶子节点.用队列维护来做的...这次学着vector动态数组+DFS回朔的方法..感觉思路更加的清晰... 关于题目的第一问...能邀请到的最多人数..so ea ...

随机推荐

  1. Django中的MiddleWare中间件

    1. middleware简介 Django的middleware的概念相当于SSH框架里面的filter的概念.中间键的作用就是对所有的request,在request前,和在response后做一 ...

  2. bzoj 1143 二分图最大独立集

    我们可以将一个点拆成两个点x,y,那么如果存在一条i->j的路径,我们就连接xi,yj,那么答案就是n-最大匹配数. 因为i->j所以对于i与j只能选一个,那么我们只需要求出来二分图的最大 ...

  3. 有关mysql的innodb_flush_log_at_trx_commit参数【转】

    一.参数解释 0:log buffer将每秒一次地写入log file中,并且log file的flush(刷到磁盘)操作同时进行.该模式下在事务提交的时候,不会主动触发写入磁盘的操作. 1:每次事务 ...

  4. 转:mysql日志(Windows下开启Mysql慢查询、通用日志)

    一.Windows下开启Mysql慢查询详解 //show variables like '%quer%';查询是否开启了慢查询!! 第一步:修改my.ini(mysql配置文件)  在my.ini中 ...

  5. CSS初步了解

    CSS 概述 个人理解为对html的扩展,对html关键字进行功能添加. CSS 指层叠样式表 (Cascading Style Sheets) 样式定义如何显示 HTML 元素 样式通常存储在样式表 ...

  6. Otto:EventBus

    Otto:EventBus 2014年6月20日 星期五 15:14 参考: http://www.mythroad.net/?p=4151 Otto 是Android系统的一个Event Bus模式 ...

  7. 反片语(UVa156)

    题目具体描述见:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=835&a ...

  8. 【DEV C++】 Error: ld returned 1 exit status

    一般出现“ld returned 1 exit status”错误都是由于函数名称拼写错误造成的,或者在一个工程中不同的函数使用了同一个函数名,暂时还未遇到其他情况.

  9. c++ primer 5 表达式

    简单总结下容易忽视的地方和易错点吧 1 常用的位操作符,leecode很多算法题都是靠位运算解决的 2 箭头操作符 -> 等价于(*  ).   对指针的成员操作 3 sizeof操作符 对 c ...

  10. 【C#日期系列(三)】--C#获取某个月的第一个星期几的年月日

    需要获取某个月的第一个星期几的年月日 简单写了一个算法 #region 计算每月第一个星期1-7是各是几号 /// <summary> /// 计算每月第一个星期1-7是各是几号 /// ...