zoukankan      html  css  js  c++  java
  • hdu 5956 The Elder

    http://acm.hdu.edu.cn/showproblem.php?pid=5956

    转移方程:dp[i]=(dis[i]-dis[j])*(dis[i]-dis[j])+P+dp[j]

    斜率优化,可持久化单调队列维护

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    #define N 100001
    
    typedef long long LL;
    
    int P;
    
    int front[N],to[N<<1],nxt[N<<1],val[N<<1],tot;
    
    int dis[N];
    
    int head,tail,q[N];
    LL dp[N];
    
    void read(int &x)
    {
        x=0; char c=getchar();
        while(!isdigit(c)) c=getchar();
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
    }
    
    void add(int u,int v,int w)
    {
        to[++tot]=v; nxt[tot]=front[u]; front[u]=tot; val[tot]=w;
        to[++tot]=u; nxt[tot]=front[v]; front[v]=tot; val[tot]=w;
    }
    
    inline double X(int i,int j) { return dis[j]-dis[i]; }
    inline double Y(int i,int j) { return 1LL*dis[j]*dis[j]+dp[j]-1LL*dis[i]*dis[i]-dp[i]; }
    
    void dfs(int x,int y)
    {
        int now_h=head,now_t=tail;
        int l=head,r=tail-2,mid,tmp=-1;
        while(l<=r)
        {
            mid=l+r>>1;
            if(Y(q[mid],q[mid+1])>=2*dis[x]*X(q[mid],q[mid+1])) tmp=mid,r=mid-1;
            else l=mid+1;
        }
        if(tmp!=-1) head=tmp;
        else head=tail-1;
        int j=q[head];
        dp[x]=1LL*(dis[x]-dis[j])*(dis[x]-dis[j])+P+dp[j];
        l=head,r=tail-2,tmp=-1;
        while(l<=r)
        {
            mid=l+r>>1;
            if(Y(q[mid],q[mid+1])*X(q[mid+1],x)<=Y(q[mid+1],x)*X(q[mid],q[mid+1])) tmp=mid,l=mid+1;
            else r=mid-1;
        }
        if(tmp!=-1) tail=tmp+2;
        else tail=head+1;
        int rr=q[tail];
        q[tail++]=x;
        for(int i=front[x];i;i=nxt[i])
            if(to[i]!=y)
            {
                dis[to[i]]=dis[x]+val[i];
                dfs(to[i],x);
            }
        head=now_h; q[tail-1]=rr; tail=now_t;
    }
    
    
    void clear()
    {
        tot=0;
        memset(front,0,sizeof(front));
    }
    
    int main()
    {
        int T;
        read(T);
        int n,u,v,w;
        while(T--)
        {
            clear();
            read(n); read(P);
            for(int i=1;i<n;++i)
            {
                read(u); read(v); read(w);
                add(u,v,w);
            }
            dp[1]=-P;
            for(int i=front[1];i;i=nxt[i])
            {
                head=0; tail=1;
                q[0]=1;
                dis[to[i]]=val[i];
                dfs(to[i],1);
            }
            LL ans=0;
            for(int i=2;i<=n;++i) ans=max(ans,dp[i]);
            cout<<ans<<'
    ';
        }
    }
  • 相关阅读:
    Yii中CreateUrl的使用总结
    scite配置文件及常用设置
    smarty中判断数组是否为空的方法
    Notepad++添加插件Funtion List 支持PHP
    类的例子1
    class的使用
    lambda 的使用汇总
    作用域
    模块的整理汇总
    函数使用的健壮性
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8468640.html
Copyright © 2011-2022 走看看