题意:

给出$DAG$,询问删掉哪个点之后最长路径最短

思路:

我们令$f[x]$表示从最远的点到达它的距离,$g[x]$表示它能够到达最远的点的距离

那么对于$(x -> y)$一条边来说,它所在的最长路径就是 $f[x] + 1 + g[y]$

我们按照拓扑序依次删点

我们发现此时删去一个点,那么可能存在的最长的路径是

和它同一层的点所在的路径,以及它前一层的点所在的路径,以及它后一层的点所在的路径

因为它只会影响到它前一层的点和后一层的点

那么我们删去它所有入边的贡献,以及它本身的$g[x]$的贡献

再更新答案后

我们加入它出边的贡献,以及它本身的$f[x]$的贡献

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #define N 500010
  5. int n, m;
  6. vector <int> G[][N];
  7. int f[N], g[N];
  8.  
  9. namespace SEG
  10. {
  11. int cnt[N << ], Max[N << ];
  12. void build(int id, int l, int r)
  13. {
  14. cnt[id] = Max[id] = ;
  15. if (l == r)
  16. return;
  17. int mid = (l + r) >> ;
  18. build(id << , l, mid);
  19. build(id << | , mid + , r);
  20. }
  21. void update(int id, int l, int r, int pos, int v)
  22. {
  23. if (pos == ) return;
  24. if (l == r)
  25. {
  26. cnt[id] += v;
  27. if (cnt[id] > ) Max[id] = pos;
  28. else Max[id] = ;
  29. return;
  30. }
  31. int mid = (l + r) >> ;
  32. if (pos <= mid) update(id << , l, mid, pos, v);
  33. else update(id << | , mid + , r, pos, v);
  34. Max[id] = max(Max[id << ], Max[id << | ]);
  35. }
  36. }
  37.  
  38. int id[N], d[][N];
  39. void Toposort()
  40. {
  41. id[] = ;
  42. memset(f, , sizeof f);
  43. memset(g, , sizeof g);
  44. queue <int> q;
  45. for (int i = ; i <= n; ++i)
  46. if (d[][i] == )
  47. q.push(i);
  48. while (!q.empty())
  49. {
  50. int u = q.front(); q.pop();
  51. id[++id[]] = u;
  52. for (int v, it = , len = G[][u].size(); it < len; ++it)
  53. {
  54. v = G[][u][it];
  55. if (--d[][v] == )
  56. {
  57. f[v] = f[u] + ;
  58. q.push(v);
  59. }
  60. }
  61. }
  62. for (int i = ; i <= n; ++i)
  63. if (d[][i] == )
  64. q.push(i);
  65. while (!q.empty())
  66. {
  67. int u = q.front(); q.pop();
  68. for (int v, it = , len = G[][u].size(); it < len; ++it)
  69. {
  70. v = G[][u][it];
  71. if (--d[][v] == )
  72. {
  73. g[v] = g[u] + ;
  74. q.push(v);
  75. }
  76. }
  77. }
  78. }
  79.  
  80. void Run()
  81. {
  82. while (scanf("%d%d", &n, &m) != EOF)
  83. {
  84. for (int i = ; i <= n; ++i)
  85. G[][i].clear(), G[][i].clear();
  86. memset(d, , sizeof d);
  87. SEG::build(, , m);
  88. for (int i = , u, v; i <= m; ++i)
  89. {
  90. scanf("%d%d", &u, &v);
  91. G[][u].push_back(v); ++d[][v];
  92. G[][v].push_back(u); ++d[][u];
  93. }
  94. Toposort();
  95. for (int i = ; i <= n; ++i)
  96. SEG::update(, , m, g[i], );
  97. int Min = (int)1e9, pos = -;
  98. for (int x, i = ; i <= n; ++i)
  99. {
  100. x = id[i];
  101. for (int v, it = , len = G[][x].size(); it < len; ++it)
  102. {
  103. v = G[][x][it];
  104. SEG::update(, , m, f[v] + + g[x], -);
  105. }
  106. SEG::update(, , m, g[x], -);
  107. int now = SEG::Max[];
  108. if (now < Min)
  109. {
  110. Min = now;
  111. pos = x;
  112. }
  113. SEG::update(, , m, f[x], );
  114. for (int v, it = , len = G[][x].size(); it < len; ++it)
  115. {
  116. v = G[][x][it];
  117. SEG::update(, , m, f[x] + + g[v], );
  118. }
  119. }
  120. printf("%d %d\n", pos, Min);
  121. }
  122. }
  123.  
  124. int main()
  125. {
  126. #ifdef LOCAL
  127. freopen("Test.in", "r", stdin);
  128. #endif
  129.  
  130. Run();
  131. return ;
  132. }

BZOJ:3832: [Poi2014]Rally的更多相关文章

  1. 【BZOJ】3832: [Poi2014]Rally

    题意 \(n(2 \le n \le 500000)\)个点\(m(1 \le m \le 1000000)\)条边的有向无环图,找到一个点,使得删掉这个点后剩余图中的最长路径最短. 分析 神题不会做 ...

  2. 3832: [Poi2014]Rally

    3832: [Poi2014]Rally 链接 分析: 首先可以考虑删除掉一个点后,计算最长路. 设$f[i]$表示从起点到i的最长路,$g[i]$表示从i出发到终点的最长路.那么经过一条边的最长路就 ...

  3. BZOJ 3832: [Poi2014]Rally

    Sol 线段树+拓扑序. 先把图的拓扑序搞出来,然后统计从起点到该点最长链,从该点到终点的最长链,然后建个起点终点,这里跟网络流很像,把它统一到一个有起点的图中,这里也要注意下细节处理.S,T的一个边 ...

  4. 【BZOJ3832】[POI2014]Rally(拓扑排序,动态规划)

    [BZOJ3832][POI2014]Rally(拓扑排序,动态规划) 题面 BZOJ,权限题 洛谷 题解 这题好强啊,感觉学了好多东西似的. 首先发现了一个图画的很好的博客,戳这里 然后我来补充一下 ...

  5. BZOJ:3441 乌鸦喝水

    bzoj:3441 乌鸦喝水 题目传送门 Description 一只乌鸦在自娱自乐,它在面前放了n个有魔力的水缸,水缸里装有无限的水. 他准备从第1个水缸飞到第n个水缸,共m次.在飞过一个水缸的过程 ...

  6. 【BZOJ】3835: [Poi2014]Supercomputer

    题意 \(n(1 \le 1000000)\)个点的有根树,\(1\)号点为根,\(q(1 \le 1000000)\)次询问,每次给一个\(k\),每一次可以选择\(k\)个未访问的点,且父亲是访问 ...

  7. 【BZOJ】3834: [Poi2014]Solar Panels

    http://www.lydsy.com/JudgeOnline/problem.php?id=3834 题意:求$max\{(i,j)\}, smin<=i<=smax, wmin< ...

  8. BZOJ3832[Poi2014]Rally——权值线段树+拓扑排序

    题目描述 An annual bicycle rally will soon begin in Byteburg. The bikers of Byteburg are natural long di ...

  9. [POI2014]Rally

    OJ题号:BZOJ3832.洛谷3573 思路: 建立超级源汇$S$和$T$,DP求出分别以$S$和$T$为源点的最长路$diss$和$dist$. 对于每条边$i$,设定一个权值$w_i=diss_ ...

随机推荐

  1. Java中自己定义缓存方式

    说说自己在开发中经常用到的写法. /** * 数据缓存 * @author * */public class DataCache {    /** 对象缓存*/    public static Ma ...

  2. Unity和虚幻的比较

    很多人从Unity开始转向虚幻4了,我目前则相反,从研究使用虚幻4,回到了Unity 5上. 前端总结的Unity和Unreal 4的一些优缺点,自己做的对比图.就先放这里了. 其实,作为引擎,各有优 ...

  3. IIS禁止xml文件访问

    今天在出现数据库账号信息泄露的时候,突然想到xml文件里面放着很多信息,而且网页能够直接访问到,这就很有问题了 开始的时候,也在IIS网站那里看到请求筛选这个设置,开始还以为不能加呢,还是同事说的.

  4. IOS深入学习(20)之Object modeling

    1 前言 本节简单的介绍了对象建模,以及需要注意的事项. 2 详述 对象建模是对设计通过一个面向对象应用检测和操作服务的对象或者类的加工.许多模型技术是可能的:Cocoa开发环境不推荐歧义性. 典型地 ...

  5. 配置linux DNS

    DNS服务器地址配置 在Linux下面,有一个默认的DNS服务器地址配置文件的设置,存放在 /etc/resolv.conf 设置方法很简单,通过编辑 vi /etc/resolv.conf 设置首选 ...

  6. 如何获取e.printStackTrace()的内容

    e.printStackTrace()通常是打印在控制台的,但是,有时候程序上线了需要看这个堆栈的内容就不容易了,一来生产环境打印的东西很多或者很少,二来有时候无法直接查看到,这个时候就需要把这些内容 ...

  7. apache工作模式worker以及prefork的切换

    apache比较常用的工作模式有worker以及prefork两种方式. 如果在编译时候不指定,系统默认的是prefork模式:如果需要换成worker模式,需要在编译的时候带上编译参数:--with ...

  8. MySQL数据库连接池导致页面登录无法查询问题解决过程

    环境为tomcat+mysql 页面卡在登录界面或者登录后点击查询卡死,tomcat日志 连接池不可达 原因连接池不可用 解决办法 停止tomcat然后等待主机所有连接mysql的链接完全关闭再启动t ...

  9. 虚拟机中CentoOs配置ip且连网

    1.修改"VMware Network Adapter VMnet8",配置IP 2.打开虚拟机,"编辑" => "虚拟网络编辑器", ...

  10. Oracle HA 之 oracle 11.2 rac库配置active dataguard

    目录 configing active dataguard for 11.2 rac. 1 一.建组.建用户.配置环境变量.内核参数等... 1 二.配置共享磁盘... 3 1)创建4块共享磁盘并fd ...