zoukankan      html  css  js  c++  java
  • 3242: [Noi2013]快餐店

    Description

    小T打算在城市C开设一家外送快餐店。送餐到某一个地点的时间与外卖店到该地点之间最短路径长度是成正比的,小T希望快餐店的地址选在离最远的顾客距离最近的地方。 快餐店的顾客分布在城市C的N 个建筑中,这N 个建筑通过恰好N 条双向道路连接起来,不存在任何两条道路连接了相同的两个建筑。任意两个建筑之间至少存在一条由双向道路连接而成的路径。小T的快餐店可以开设在任一建筑中,也可以开设在任意一条道路的某个位置上(该位置与道路两端的建筑的距离不一定是整数)。 现给定城市C的地图(道路分布及其长度),请找出最佳的快餐店选址,输出其与最远的顾客之间的距离。



    Input

    第一行包含一个整数N,表示城市C中的建筑和道路数目。
    接下来N行,每行3个整数,Ai,Bi,Li(1≤i≤N;Li>0),表示一条道路连接了建筑Ai与Bi,其长度为Li 。

    Output

    仅包含一个实数,四舍五入保留恰好一位小数,表示最佳快餐店选址距离最远用户的距离。
    注意:你的结果必须恰好有一位小数,小数位数不正确不得分。
    Sample Input
    1 2 1
    1 4 2
    1 3 2
    2 4 1
    Sample Output
    2.0
    HINT



    数据范围

    对于 10%的数据,N<=80,Li=1;

    对于 30%的数据,N<=600,Li<=100;

    对于 60% 的数据,N<=2000,Li<=10^9;

    对于 100% 的数据,N<=10^5,Li<=10^9

    首先把环求出来,然后枚举删掉环上某条边,再算出现在的直径,然后取个min

    我们先求出不经过环的最长链,然后每次都只用做经过环的最长链了

    删掉一条边我们得到了一条链,每个点有两个属性,一个是d[i],表示不走链最长的距离,一个是S[i],表示从1走环上的边到i的距离

    我们要求的是max{S[j]-S[i]+d[i]+d[j]},所以我们维护max{S[i]+d[i]}和max{d[i]-S[i]},但是两个点不能是同一个点所以再维护一下次小值和最大值的编号,用线段树

      1 const
      2     maxn=100100;
      3     inf=10000000000000000000000000000;
      4 type
      5     node=record
      6         max:array[0..1]of double;
      7         id,l,r,lc,rc:longint;
      8     end;
      9 var
     10     first,huan,fa:array[0..maxn]of longint;
     11     d:array[0..maxn,0..1]of double;
     12     next,last:array[0..maxn*2]of longint;
     13     l,len,a:array[0..maxn*2]of double;
     14     vis:array[0..maxn]of boolean;
     15     f:array[0..maxn*4]of node;
     16     n,tot,cnt,num,root1,root2:longint;
     17     ans,ans1,s:double;
     18  
     19 function max(x,y:double):double;
     20 begin
     21     if x>y then exit(x);
     22     exit(y);
     23 end;
     24  
     25 function min(x,y:double):double;
     26 begin
     27     if x<y then exit(x);
     28     exit(y);
     29 end;
     30  
     31 procedure insert(x,y:longint;z:double);
     32 begin
     33     inc(tot);
     34     last[tot]:=y;
     35     next[tot]:=first[x];
     36     first[x]:=tot;
     37     l[tot]:=z;
     38 end;
     39  
     40 procedure dfs1(x:longint);
     41 var
     42     i,j:longint;
     43 begin
     44     i:=first[x];
     45     vis[x]:=true;
     46     while i<>0 do
     47         begin
     48             if cnt>0 then exit;
     49             if (last[i]<>fa[x]) and vis[last[i]] then
     50             begin
     51                 j:=x;
     52                 len[last[i]]:=l[i];
     53                 while j<>fa[last[i]] do
     54                     begin
     55                         inc(cnt);
     56                         huan[cnt]:=j;
     57                         j:=fa[j];
     58                     end;
     59             end;
     60             if not vis[last[i]] then
     61             begin
     62                 fa[last[i]]:=x;
     63                 len[last[i]]:=l[i];
     64                 dfs1(last[i]);
     65             end;
     66             i:=next[i];
     67         end;
     68 end;
     69  
     70 procedure dfs2(x:longint);
     71 var
     72     i:longint;
     73 begin
     74     vis[x]:=true;
     75     i:=first[x];
     76     while i<>0 do
     77         begin
     78             if not vis[last[i]] then
     79             begin
     80                 dfs2(last[i]);
     81                 if d[last[i],0]+l[i]>d[x,0] then
     82                     begin
     83                         d[x,1]:=d[x,0];
     84                         d[x,0]:=d[last[i],0]+l[i];
     85                     end
     86                 else
     87                     if d[last[i],0]+l[i]>d[x,1] then d[x,1]:=d[last[i],0]+l[i];
     88             end;
     89             i:=next[i];
     90         end;
     91     if ans<d[x,0]+d[x,1] then ans:=d[x,0]+d[x,1];
     92 end;
     93  
     94 procedure new(x:longint);
     95 begin
     96     f[x].max:=f[f[x].lc].max;
     97     f[x].id:=f[f[x].lc].id;
     98     if f[f[x].rc].max[0]>f[x].max[0] then
     99         begin
    100             f[x].max[1]:=f[x].max[0];
    101             f[x].max[0]:=f[f[x].rc].max[0];
    102             f[x].id:=f[f[x].rc].id;
    103         end
    104     else
    105         if f[f[x].rc].max[0]>f[x].max[1] then f[x].max[1]:=f[f[x].rc].max[0];
    106     if f[f[x].rc].max[1]>f[x].max[1] then f[x].max[1]:=f[f[x].rc].max[1];
    107 end;
    108  
    109 procedure build(l,r:longint);
    110 var
    111     now,mid:longint;
    112 begin
    113     inc(num);now:=num;
    114     f[now].l:=l;f[now].r:=r;
    115     if l=r then
    116     begin
    117         f[now].max[0]:=a[l];
    118         f[now].max[1]:=-inf;
    119         f[now].id:=l;
    120         exit;
    121     end;
    122     mid:=(l+r)>>1;
    123     f[now].lc:=num+1;build(l,mid);
    124     f[now].rc:=num+1;build(mid+1,r);
    125     new(now);
    126 end;
    127  
    128 procedure add(now,x:longint;y:double);
    129 var
    130     mid:longint;
    131 begin
    132     if f[now].l=f[now].r then
    133     begin
    134         f[now].max[0]:=y;
    135         exit;
    136     end;
    137     mid:=(f[now].l+f[now].r)>>1;
    138     if x<=mid then
    139         add(f[now].lc,x,y)
    140     else
    141         add(f[now].rc,x,y);
    142     new(now);
    143 end;
    144  
    145 procedure main;
    146 var
    147     i,x,y:longint;
    148     z:double;
    149 begin
    150     read(n);
    151     for i:=1 to n do
    152         begin
    153             read(x,y,z);
    154             insert(x,y,z);
    155             insert(y,x,z);
    156         end;
    157     dfs1(1);
    158     for i:=1 to n do vis[i]:=false;
    159     for i:=1 to cnt do vis[huan[i]]:=true;
    160     for i:=1 to cnt do dfs2(huan[i]);
    161     z:=0;
    162     for i:=1 to cnt do
    163         begin
    164             a[i]:=z+d[huan[i],0];
    165             z:=z+len[huan[i]];
    166         end;
    167     root1:=num+1;build(1,cnt);
    168     z:=0;
    169     for i:=1 to cnt do
    170         begin
    171             a[i]:=d[huan[i],0]-z;
    172             z:=z+len[huan[i]];
    173         end;
    174     root2:=num+1;build(1,cnt);
    175     ans1:=inf;
    176     for i:=1 to cnt do
    177         begin
    178             if f[root1].id<>f[root2].id then
    179                 ans1:=min(ans1,f[root1].max[0]+f[root2].max[0])
    180             else
    181                 ans1:=min(ans1,max(f[root1].max[1]+f[root2].max[0],f[root1].max[0]+f[root2].max[1]));
    182             s:=s+len[huan[i]];
    183             add(root1,i,z-len[huan[i]]+d[huan[i],0]+s);
    184             add(root2,i,d[huan[i],0]-z+len[huan[i]]-s);
    185         end;
    186     ans:=max(ans,ans1);
    187     writeln(ans/2:0:1);
    188 end;
    189  
    190 begin
    191     main;
    192 end.
    View Code
  • 相关阅读:
    Metropolis(大都会):以太坊网络的下一个阶段
    《区块链开发技术综述》乱弹
    Ext.Net学习笔记09:Ext.Net Store的用法
    Ext.Net学习笔记09:Ext.Net Store的用法
    Spring整合redis配置文件详解
    Spring整合redis配置文件详解
    Spring整合redis配置文件详解
    Spring整合redis配置文件详解
    Android环境配置----在Ubuntu上安装JDK
    Android环境配置----在Ubuntu上安装JDK
  • 原文地址:https://www.cnblogs.com/Randolph87/p/3788640.html
Copyright © 2011-2022 走看看