传送门:http://www.hsin.hr/coci/archive/2015_2016/

进去之后点最下面那个。

这道题没有想出来,可惜了,其实不难的。

题目是两个“源”的,我们先考虑单源的问题。先把这个源拉成树根,然后设f(i)为以结点i为树根的子树,全部收到文件所需要的时间,由于同一时间,结点i只能向其中一个子结点传送文件,那么假设son(i, j)表示结点i的第j个子结点(程序中不需要这个数组,这里只是为了叙述方便),那么f(i) = max{ j + f( son(i, j) )}。为了让这个max值最小,很显然需要把f( son(i, j) )按照从大到小排,即子树所需时间越长的,结点i就应该越早传文件给它。这样子就解决了单源的问题。

那么再考虑双源的。考虑从a到b的路径,若a到b的路径上,存在相邻的c,d两个点,很显然,在最佳方案里一定会有文件从a传到c,从b传到d,所以,如果把(c, d)这条边断开也不会影响到答案,这就变成了求两次单源的问题。因此,若把a到b的路径上的边按离a从远到近编号,设f_a(i)表示断开边i后,a所属的那棵树所需要的时间,设f_b(i)表示断开边i后,b所属的那棵树所需要的时间,那么最终答案ans =  min{ max{f_a(i), f_b(i)} }。

这样会tle(我会说std有一个点,在我们学校的垃圾电脑上跑了92s吗?时限可是2s啊喂!你这标程怎么写的!),因此需要优化。很显然(又是显然),断开的边i离a越远,f_a(i)就会越大(其实也可以取等),f_b(i)就会越小(其实也可以取等),因此可以再二分一下断哪条边,就ok了!复杂度是O(n * (logn)^2)

p.s.主函数的前三行是开栈,以免递归爆栈。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <vector>
  4. #include <algorithm>
  5.  
  6. const int maxn = 300005;
  7.  
  8. int n, a, b, t1, t2;
  9. int head[maxn], to[maxn << 1], next[maxn << 1], lb, fa[maxn];
  10. char mark[maxn];
  11. std::vector<int> fson[maxn];
  12. struct edge {
  13. int u, v;
  14. } e[maxn];
  15. int idx;
  16.  
  17. inline void ist(int aa, int ss) {
  18. to[lb] = ss;
  19. next[lb] = head[aa];
  20. head[aa] = lb;
  21. ++lb;
  22. }
  23. void dfs(int r, int p) {
  24. fa[r] = p;
  25. for (int j = head[r]; j != -1; j = next[j]) {
  26. if (to[j] != p) {
  27. dfs(to[j], r);
  28. }
  29. }
  30. }
  31. int get_ans(int r, int p, int mar) {
  32. fson[r].clear();
  33. int son_num = 0, mx = 0;
  34. for (int j = head[r]; j != -1; j = next[j]) {
  35. if (to[j] != p && mark[to[j]] != -mar) {
  36. fson[r].push_back(get_ans(to[j], r, mar));
  37. ++son_num;
  38. }
  39. }
  40. std::sort(fson[r].begin(), fson[r].end());
  41. for (std::vector<int>::iterator it = fson[r].begin(); it != fson[r].end(); ++it) {
  42. mx = std::max(mx, *it + son_num);
  43. --son_num;
  44. }
  45. return mx;
  46. }
  47.  
  48. int main(void) {
  49. int size = 256 << 20; // 256MB
  50. char *p = (char*)malloc(size) + size;
  51. __asm__("movl %0, %%esp\n" :: "r"(p));
  52. freopen("torrent.in", "r", stdin);
  53. freopen("torrent.out", "w", stdout);
  54. memset(head, -1, sizeof head);
  55. memset(next, -1, sizeof next);
  56. scanf("%d%d%d", &n, &a, &b);
  57. for (int i = 1; i < n; ++i) {
  58. scanf("%d%d", &t1, &t2);
  59. ist(t1, t2);
  60. ist(t2, t1);
  61. }
  62.  
  63. dfs(a, 0);
  64. for (int i = b; i != a; i = fa[i]) {
  65. e[idx++] = (edge){fa[i], i};
  66. }
  67.  
  68. int left = 0, right = idx - 1, mid;
  69. while (left < right) {
  70. mid = (left + right) >> 1;
  71. mark[e[mid].u] = -1;
  72. mark[e[mid].v] = 1;
  73. if (get_ans(a, 0, -1) > get_ans(b, 0, 1)) {
  74. left = mid + 1;
  75. }
  76. else {
  77. right = mid;
  78. }
  79. mark[e[mid].u] = mark[e[mid].v] = 0;
  80. }
  81. if (!left) {
  82. mark[e[0].u] = -1;
  83. mark[e[0].v] = 1;
  84. printf("%d\n", get_ans(b, 0, 1));
  85. }
  86. else {
  87. int ans1 = -666, ans2 = -666;
  88. mark[e[left].u] = -1;
  89. mark[e[left].v] = 1;
  90. ans1 = get_ans(b, 0, 1);
  91. mark[e[left].u] = mark[e[left].v] = 0;
  92.  
  93. mark[e[left - 1].u] = -1;
  94. mark[e[left - 1].v] = 1;
  95. ans2 = get_ans(a, 0, -1);
  96. printf("%d\n", std::min(ans1, ans2));
  97. }
  98. return 0;
  99. }

  

[coci2015-2016 coii] torrent【树形dp 二分】的更多相关文章

  1. 两种解法-树形dp+二分+单调队列(或RMQ)-hdu-4123-Bob’s Race

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4123 题目大意: 给一棵树,n个节点,每条边有个权值,从每个点i出发有个不经过自己走过的点的最远距离 ...

  2. hdu 3586 Information Disturbing(树形dp + 二分)

    本文出自   http://blog.csdn.net/shuangde800 题目链接:   hdu-3586 题意 给一棵n个节点的树,节点编号为1-n,根节点为1.每条边有权值,砍掉一条边要花费 ...

  3. BZOJ3420[POI2013]Triumphal arch&BZOJ5174[Jsoi2013]哈利波特与死亡圣器——树形DP+二分答案

    题目大意: 给一颗树,1号节点已经被染黑,其余是白的,两个人轮流操作,一开始B在1号节点,A选择k个点染黑,然后B走一步,如果B能走到A没染的节点则B胜,否则当A染完全部的点时,A胜.求能让A获胜的最 ...

  4. hdu 3586 树形dp+二分

    题目大意:给定n个敌方据点,1为司令部,其他点各有一条边相连构成一棵 树,每条边都有一个权值cost表示破坏这条边的费用,叶子节点为前线.现要切断前线和司令部的联系,每次切断边的费用不能超过上限lim ...

  5. 【BZOJ3872】[Poi2014]Ant colony 树形DP+二分

    [BZOJ3872][Poi2014]Ant colony Description 给定一棵有n个节点的树.在每个叶子节点,有g群蚂蚁要从外面进来,其中第i群有m[i]只蚂蚁.这些蚂蚁会相继进入树中, ...

  6. [hdu3586]Information Disturbing树形dp+二分

    题意:给出一棵带权无向树,以及给定节点1,总约束为$m$,找出切断与所有叶子节点联系每条边所需要的最小价值约束. 解题关键:二分答案,转化为判定性问题,然后用树形dp验证答案即可. dp数组需要开到l ...

  7. HDU - 3586 Information Disturbing 树形dp二分答案

    HDU - 3586 Information Disturbing 题目大意:从敌人司令部(1号节点)到前线(叶子节点)的通信路径是一个树形结构,切断每条边的联系都需要花费w权值,现在需要你切断前线和 ...

  8. HDU 3586 Information Disturbing 树形DP+二分

    Information Disturbing Problem Description   In the battlefield , an effective way to defeat enemies ...

  9. hdu3586 Information Disturbing 树形DP+二分

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3586 题目大意:给定n个敌方据点,编号1为司令部,其他点各有一条边相连构成一棵树,每条边都有一个权值c ...

随机推荐

  1. 关于JavaScript的事件触发

    突然知道JavaScript底层是怎么实现事件触发的,找到一个博客,功力不够,看的很迷糊,记载这里吧,后面再研究. [探讨]javascript事件机制底层实现原理

  2. platform_set_drvdata()/platform_get_drvdata()/container_of()【转】

    本文转载自:http://blog.csdn.net/angle_birds/article/details/8443695 platform_set_drvdata(struct platform_ ...

  3. 棋盘覆盖问题 (粉书 P230 【递归】** )

    转载自:http://blog.csdn.net/akof1314/article/details/5423608  (赞) 在一个 2^k * 2^k 个方格组成的棋盘中,若恰有一个方格与其它方格不 ...

  4. 基于BASYS2的VHDL程序——数字钟

    在编电子表时发现FPGA求余,取模只能针对2的次方.毕竟是数字的嘛! 时钟用到了动态刷新数码管.以一个大于50Hz的速度刷新每一个数码管. 因为数码管只有四个,只写了分针和秒针. 代码如下: libr ...

  5. hdu-5726 GCD(rmq)

    题目链接: GCD Time Limit: 10000/5000 MS (Java/Others)     Memory Limit: 65536/65536 K (Java/Others) Prob ...

  6. js 改变对象的引用地址

    在业务处理中我们经常会碰到列表中有编辑和新增按钮,为了能够提高代码的公用性,我们经常会使用同一组件处理. 这样会出现一个问题就是编辑的时候直接把对象传过去,直接赋值,引用地址是同一个,所以不管修改了那 ...

  7. 【Data Structure & Algorithm】求子数组的最大和

    求子数组的最大和 题目:输入一个整型数组,数组里有正数和负数.数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和.求所有子数组的和的最大值,要求时间复杂度为O(n).例如输入数组为1, - ...

  8. PHP文件操作功能函数大全

    PHP文件操作功能函数大全 <?php /* 转换字节大小 */ function transByte($size){ $arr=array("B","KB&quo ...

  9. easyui更改messager的OkCancel按钮为(中文)确定取消

    jquery-easyui默认情况下,消息框的按钮文字是英文的OK  Cancel,但可以通过提供的方法进行修改,如: $.extend($.messager.defaults,{ ok:" ...

  10. codeforces 813C The Tag Game 树+dfs追击问题

    C. The Tag Gametime limit per test1 secondmemory limit per test256 megabytesinputstandard inputoutpu ...