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<<'
    ';
        }
    }
  • 相关阅读:
    HDU 1203 01背包变形题,(新思路)
    HDU 2955 变形较大的01背包(有意思,新思路)
    HDU 2191(多重背包转换为01背包来做)
    HDU 1114(没有变形的完全背包)
    HDU2546(01背包加一点点变形)
    HDU 1950(LIS)
    c模拟 页式管理页面置换算法之FIFO
    HDU 1257 最少拦截系统(贪心 or LIS)
    路由选择(codevs 1062)
    钓鱼(洛谷 P1717)
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8468640.html
Copyright © 2011-2022 走看看