货车运输[辽宁2014年省队互测一]

题目描述

SOL 奇奇怪怪的码农题。

  我们考虑是一颗树怎么做,我们发现我们可以离线做,把车的限速排序,依次处理,我们首先是树剖,把边分成两类,最高速度小于车速和大于车速的。每次做之前先把最高速度小于当前车速的加到另一类。强行树剖维护。至于多出来的那一条边,我们记其练了A , B,记我们原来的始末位置为X,Y,所以我们有3条可行的路径,X-Y,X-a-b-Y,X-b-a-Y。取min即可。

#pragma GCC optimize("-O2")
#include<bits/stdc++.h>
#define sight(c) ('0'<=c&&c<='9')
#define eho(x) for (int i=head[x];i;i=net[i])
#define LL long long
#define L(x) (x&-x)
#define inf (1<<26)
//#define int long long
#define LL long long
#define N 100007
#define db long double
using namespace std;
int VV,n,fall[N<<1],net[N<<1],head[N],tot,siz[N],son[N],usd[N],be[N],
ed[N],f[N],tim,top[N],dep[N],m,q,v[N],w[N],id,Top;
db HCHO,Ans,ans[N];
bool U[N];
inline void read(int &x){
    static char c;
    for (c=getchar();!sight(c);c=getchar());
    for (x=0;sight(c);c=getchar())x=x*10+c-48;
}
inline void read(LL &x){
    static char c;
    for (c=getchar();!sight(c);c=getchar());
    for (x=0;sight(c);c=getchar())x=x*10+c-48;
}
struct Node {
    int a,b,v,id;
    inline bool operator <(const Node &a)const{return v<a.v;}
}T[N];
struct edge {
    int a,b,l,x;
    bool operator <(const edge& a)const{return x>a.x;}
}L[N]; 
struct Tree {
    db a[N];
    inline void add(int x,db dla){for(;x<N;x+=L(x))a[x]+=dla;}
    inline db query(int x){db o;for(o=0;x;x-=L(x))o+=a[x];return o;}
}A1,A2;
inline void add(int x,int y){fall[++tot]=y; net[tot]=head[x]; head[x]=tot;}
void dfs(int x,int fa){
    U[x]=1;
    siz[x]=1; son[x]=0; dep[x]=dep[fa]+1;
    eho(x) if (fall[i]^fa&&!U[fall[i]]) {
        usd[i>>1]=fall[i]; ed[fall[i]]=i>>1; dfs(fall[i],x);
        siz[x]+=siz[fall[i]];
        siz[fall[i]]<siz[son[x]]?:son[x]=fall[i];
    }
}
void dfs2(int x,int fa,int op){
//  t[++tim]=x; 
    be[x]=++tim; top[x]=op; f[x]=fa;
    if (son[x]) dfs2(son[x],x,op);
    eho(x) if (fall[i]^fa&&fall[i]^son[x]&&
    (i>>1)^id) dfs2(fall[i],x,fall[i]);
}
inline db min(db x,db y){return x<y?x:y;}
db ask(int x,int y) {
    Ans=0;
    while (top[x]^top[y]) {
        if (dep[top[x]]<dep[top[y]]) swap(x,y);
        Ans+=(A1.query(be[x])-A1.query(be[top[x]]-1))/VV+A2.query(be[x])-A2.query(be[top[x]]-1);
        x=f[top[x]];
    } if (dep[x]>dep[y]) swap(x,y);
    Ans+=(A1.query(be[y])-A1.query(be[x]))/VV+A2.query(be[y])-A2.query(be[x]);
    return Ans;
}
signed main() {
    read(n);read(m);read(q); add(0,0);
    for (int i=1;i<=n;i++) read(L[i].a),read(L[i].b),read(L[i].l),read(L[i].x);
    sort(L+1,L+n+1);
    for (int i=1;i<=n;i++) add(L[i].a,L[i].b),add(L[i].b,L[i].a);
    for (int i=1;i<=m;i++) read(v[i]),read(w[i]); v[0]=inf;
    dfs(1,0);
    for (int i=1;i<=n;i++) if (!usd[i]) {id=i;break;}
    for (int i=1;i<=q;i++) read(T[i].a),read(T[i].b),read(T[i].v),T[i].id=i;
    dfs2(1,0,1);
    #define top Top
    sort(T+1,T+q+1); top=1;
    for (int i=1;i<=n;i++) if (usd[i]) A1.add(be[usd[i]],(LL)L[i].l*w[L[i].x]);
    for (int i=1;i<=q;i++) {
      VV=T[i].v;
      HCHO=T[i].v>v[L[id].x]?(LL)L[id].l*w[L[id].x]*1.0/v[L[id].x]:(LL)L[id].l*w[L[id].x]*1.0/T[i].v;
      while (T[i].v>=v[L[top].x]) {
       if (usd[top]) {
       A1.add(be[usd[top]],(db)-1.0*L[top].l*w[L[top].x]);
       A2.add(be[usd[top]],(LL)L[top].l*w[L[top].x]*1.0/v[L[top].x]);}
      top++;}
        ans[T[i].id]=min(ask(T[i].a,T[i].b),
         min(ask(T[i].a,L[id].a)+ask(T[i].b,L[id].b),
         ask(T[i].a,L[id].b)+ask(T[i].b,L[id].a))+HCHO
         );
    }
    for (int i=1;i<=q;i++) printf("%.10Lf\n",ans[i]);return 0;
}

 

posted @ 2018-01-06 20:03  泪寒之雪  阅读(172)  评论(0编辑  收藏  举报