BZOJ 4326:NOIP2015 运输计划(二分+差分+lca)

NOIP2015 运输计划
Description
公元 2044 年,人类进入了宇宙纪元。L 国有 n 个星球,还有 n−1 条双向航道,每条航道建立在两个星球之间,这 n−1 条航道连通了 L 国的所有星球。小 P 掌管一家物流公司, 该公司有很多个运输计划,每个运输计划形如:有一艘物流飞船需要从 ui 号星球沿最快的宇航路径飞行到 vi 号星球去。显然,飞船驶过一条航道是需要时间的,对于航道 j,任意飞船驶过它所花费的时间为 tj,并且任意两艘飞船之间不会产生任何干扰。为了鼓励科技创新, L 国国王同意小 P 的物流公司参与 L 国的航道建设,即允许小P 把某一条航道改造成虫洞,飞船驶过虫洞不消耗时间。在虫洞的建设完成前小 P 的物流公司就预接了 m 个运输计划。在虫洞建设完成后,这 m 个运输计划会同时开始,所有飞船一起出发。当这 m 个运输计划都完成时,小 P 的物流公司的阶段性工作就完成了。如果小 P 可以自由选择将哪一条航道改造成虫洞, 试求出小 P 的物流公司完成阶段性工作所需要的最短时间是多少?
Input
第一行包括两个正整数 n,m,表示 L 国中星球的数量及小 P 公司预接的运输计划的数量,星球从 1 到 n 编号。接下来 n−1 行描述航道的建设情况,其中第 i 行包含三个整数 ai,bi 和 ti,表示第 i 条双向航道修建在 ai 与 bi 两个星球之间,任意飞船驶过它所花费的时间为 ti。数据保证 1≤ai,bi≤n 且 0≤ti≤1000。接下来 m 行描述运输计划的情况,其中第 j 行包含两个正整数 uj 和 vj,表示第 j 个运输计划是从 uj 号星球飞往 vj号星球。数据保证 1≤ui,vi≤n
Output
输出文件只包含一个整数,表示小 P 的物流公司完成阶段性工作所需要的最短时间。
Sample Input
6 3
1 2 3
1 6 4
3 1 7
4 3 6
3 5 5
3 6
2 5
4 5
Sample Output
11
HINT
将第 1 条航道改造成虫洞: 则三个计划耗时分别为:11,12,11,故需要花费的时间为 12。
将第 2 条航道改造成虫洞: 则三个计划耗时分别为:7,15,11,故需要花费的时间为 15。
将第 3 条航道改造成虫洞: 则三个计划耗时分别为:4,8,11,故需要花费的时间为 11。
将第 4 条航道改造成虫洞: 则三个计划耗时分别为:11,15,5,故需要花费的时间为 15。
将第 5 条航道改造成虫洞: 则三个计划耗时分别为:11,10,6,故需要花费的时间为 11。
故将第 3 条或第 5 条航道改造成虫洞均可使得完成阶段性工作的耗时最短,需要花费的时间为 11。
Source

分析:

二分还是很显然的,二分花费时间,对于这棵树,没超过这个时间的计划可以不用管,对于超过这一时间的运输计划,我们需要利用虫洞使它们时间缩小至允许范围内。显然,这个虫洞必须要在所有超时计划路径的交集中,同时超时计划中最耗时的点减去虫洞的边权后必须在允许范围内。我们可以利用差分,对于每个超时计划,我们在起点和终点+1,并在它们lca点与其父亲连的边-2,从下往上统计,如果某点当前数字和=超时计划总数,并且使所有计划都在允许时间内,则该点可作为虫洞。

别的网站测有95分,bzoj空间太小了会爆

代码:

program transport;
type
  point=^node;
   node=record
     x,v:longint; next:point;
   end;
const
  num=300000;
var
  a:array[0..num]of point;
  q:array[0..num*3]of longint;
  h:array[0..25,0..num*3]of longint;
  w:array[0..num,1..2]of longint;
  r,c,b,f,d,s,v:array[0..num]of longint;
  pl:array[0..25]of longint;
  n,i,m,x,y,t:longint;  len,make,maxn:longint;
procedure add(x,y,v:longint);
var p:point;
begin
  new(p); p^.x:=y; p^.v:=v; p^.next:=a[x]; a[x]:=p;
end;
procedure dfs(x,y,deep:longint);
var p:point;
begin
  new(p); p:=a[x]; d[x]:=deep; inc(len); q[len]:=x; r[x]:=len;
  while p<>nil do
   begin
     if p^.x<>y then begin s[p^.x]:=s[x]+p^.v; dfs(p^.x,x,deep+1); end; p:=p^.next;  inc(len); q[len]:=x;
   end;
end;
procedure dfs1(x,y,sum:longint);
var p:point;
begin
  new(p); p:=a[x];
  while p<>nil do
   begin
     if p^.x<>y then
      begin
         dfs1(p^.x,x,sum); if c[p^.x]>=sum then if p^.v>make then make:=p^.v;
         inc(c[x],c[p^.x]); end;
     p:=p^.next;
   end;
  inc(c[x],b[x]);
end;
procedure work;
var i,j,x,y:longint;
begin
  for i:=1 to len do h[0,i]:=q[i]; pl[0]:=1;
  for i:=1 to trunc(ln(len)/ln(2)) do pl[i]:=pl[i-1]*2;
  for i:=1 to trunc(ln(len)/ln(2)) do
    for j:=1 to len+1-2*i do
      begin
        x:=h[i-1,j]; y:=h[i-1,j+pl[i-1]];
        if d[x]<d[y] then h[i,j]:=x else h[i,j]:=y;
      end;
end;
function lca(x,y:longint):longint;
var i,t:longint;
begin
  x:=r[x]; y:=r[y];
  if x>y then begin t:=x; x:=y; y:=t; end;
  i:=trunc(ln(y-x+1)/ln(2));
  x:=h[i,x];  y:=h[i,y-pl[i]+1];
  if d[x]<d[y] then exit(x) else exit(y);
end;
function cheak(mid:longint):boolean;
var i,maxant,sum:longint;
begin
  fillchar(c,sizeof(c),0);fillchar(b,sizeof(b),0); maxant:=0; sum:=0;
  for i:=1 to m do
  if v[i]>mid then
   begin
     inc(c[w[i,1]]); inc(c[w[i,2]]); dec(b[f[i]],2);
     if v[i]>maxant then maxant:=v[i];
     inc(sum);
   end;
  make:=0;
  dfs1(1,0,sum);
  if make=0 then exit(false);
  if maxant-make>mid then exit(false);
  exit(true);
end;
procedure solve;
var l,r,ans,mid:longint;
begin
  l:=1; r:=maxn*2;
  while l<=r do
    begin
      mid:=(l+r) div 2;
      if cheak(mid) then begin ans:=mid; r:=mid-1; end else l:=mid+1;
    end;
  writeln(ans);
end;
begin
  readln(n,m);
  fillchar(r,sizeof(r),0);
  for i:=1 to n-1 do
   begin
     readln(x,y,t);
     add(x,y,t); add(y,x,t);
   end;
  len:=0;
  s[1]:=0;  dfs(1,0,1);
  work;
  for i:=1 to m do
   begin
     readln(w[i,1],w[i,2]);
     f[i]:=lca(w[i,1],w[i,2]);
     v[i]:=s[w[i,1]]+s[w[i,2]]-2*s[f[i]];
     if v[i]>maxn then maxn:=v[i];
   end;
  solve;
end.

时间: 2024-10-21 08:19:01

BZOJ 4326:NOIP2015 运输计划(二分+差分+lca)的相关文章

BZOJ 4326 NOIP2015 运输计划 (二分+树上差分)

题意:中文题. 析:首先二分是很容易想出来的,然后主要是判断这个解合不合法,先二分答案 mid,因为有 m 个计划,所以只要添加虫洞的肯定是所有的时间长于 mid 的计划 中,也就是是那些的共同边,这个就可以用树上差分来做了,假设 s 到 t,那么让in[s]++,in[t]++,in[lca(s, t)] -= 2,其中in 表示的是 该结点与其父结点的边的计数,最后再跑一次dfs,把所有的权值都累加上去,这样就能知道哪些是共同的边了. 代码如下: #pragma comment(linker

BZOJ 4326 NOIP2015 运输计划

题 OvO http://www.lydsy.com/JudgeOnline/problem.php?id=4326 解 首先二分答案(时间), 对于每个时间,在检查是否可以做到的时候,遍历每个路线,记录下那些超过时间限制的路线. 然后问题就是要找到一条边,被所有超时间限制的路线覆盖,记录这条边的长度.如果去掉这条边之后不超时间则该时间限制可行,否则不可行. 记超时间的路线数量为num.对于每一个超过时间的路线,记其起点为a,终点为b,c是和b的lca,开一个tag数组,把a,b节点的tag+1

[NOIP2015]运输计划 D2 T3 LCA+二分答案+差分数组

[NOIP2015]运输计划 D2 T3 Description 公元2044年,人类进入了宇宙纪元. L国有n个星球,还有n-1条双向航道,每条航道建立在两个星球之间,这n-1条航道连通了L国的所有星球. 小P掌管一家物流公司,该公司有很多个运输计划,每个运输计划形如:有一艘物流飞船需要从ui号星球沿最快的宇航路径飞行到vi号星球去.显然,飞船驶过一条航道是需要时间的,对于航道j,任意飞船驶过它所花费的时间为tj,并且任意两艘飞船之间不会产生任何干扰. 为了鼓励科技创新,L国国王同意小P的物流

Noip2015 运输计划 树上差分 二分答案

Code: #include<cstring> #include<cstdio> #include<algorithm> #include<string> using namespace std; void setIO(string a){freopen((a+".in").c_str(),"r",stdin);} #define maxn 300090 #define logn 20 int head[maxn],t

BZOJ 4326 树链剖分+二分+差分+记忆化

去年NOIP的时候我还不会树链剖分! 还是被UOJ 的数据卡了一组. 差分的思想还是很神啊! 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 #include <ctime> 6 #include <cstdlib> 7 using namespace std; 8 const int Maxn=300100

NOIP2015 运输计划(二分+LCA+差分)

4326: NOIP2015 运输计划 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 308  Solved: 208[Submit][Status][Discuss] Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航道建立在两个星球之间,这 n−1 条航道连通了 L 国的所有星球.小 P 掌管一家物流公司, 该公司有很多个运输计划,每个运输计划形如:有一艘物流飞船需要从 ui

树链剖分-Hello!链剖-[NOIP2015]运输计划-[填坑]

This article is made by Jason-Cow.Welcome to reprint.But please post the writer's address. http://www.cnblogs.com/JasonCow/ [NOIP2015]运输计划    Hello!链剖.你好吗? 题意: 给出一棵n个节点的带权树,m对树上点对 现在允许删除一条边,(权值修改为0) 输出: 最小化的点对间最大距离 1.链剖 2.树上差分 3.二分 链剖我就不多说了,就是两dfs 注意

AC日记——[NOIP2015]运输计划 cogs 2109

[NOIP2015] 运输计划 思路: 树剖+二分: 代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define maxn 300005 #define INF 0x7fffffff int n,deep[maxn],dis[maxn],dis_[maxn],f[maxn],top[maxn]; i

数据结构(树链剖分):COGS 2109. [NOIP2015] 运输计划

2109. [NOIP2015] 运输计划 ★★★   输入文件:transport.in   输出文件:transport.out   简单对比时间限制:1 s   内存限制:256 MB [题目描述] 公元 2044 年,人类进入了宇宙纪元. L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n-1 条航道连通了 L 国的所有星球. 小 P 掌管一家物流公司,该公司有很多个运输计划,每个运输计划形如:有一艘物 流飞船需要从 ui 号星球沿最快的宇航路径飞行到 v