[bzoj1758][Wc2010]重建计划——长链剖分+线段树+分数规划

题目大意:

给定一颗带权的树,求一条长路在\([L,R]\)的路径,权值的平均数最大。

思路:

显然先分数规划,二分答案,然后考虑怎么check。
考虑一个简单的树型DP,记\(f_{i,j}\)为i子树内距离i为j的点中路径长度和最大是多少,然后一个点可以从它的儿子转移过来,在转移的时候每次记录前缀枚举新添加进来的子树深度计算一遍答案。
这样复杂度\(O(n^2)\),发现转移和子树的深度有关,然后第一颗转移的子树只是涉及到了下标的改变,于是考虑长链剖分优化复杂度,每一次直接先找到重儿子继承,然后再枚举每一条轻边,暴力转移每一条轻边上面的链。
由于有长度限制,考虑将每一条长链放到线段树上维护,查询的时候直接在线段树上面查询区间最大值即可。
有的打法需要支持线段树的区间修改,但其实没有这个必要,一个trick就是将\(f_{i,j}\)表示为距离i深度为j的点距离根的最长路径长度,计算时再考虑lca的贡献即可。

#include<bits/stdc++.h>
 
#define REP(i,a,b) for(int i=a,i##_end_=b;i<=i##_end_;++i)
#define DREP(i,a,b) for(int i=a,i##_end_=b;i>=i##_end_;--i)
#define debug(x) cout<<#x<<"="<<x<<" "
#define fi first
#define se second
#define mk make_pair
#define pb push_back
typedef long long ll;
 
using namespace std;
 
void File(){
    freopen("bzoj1758.in","r",stdin);
    freopen("bzoj1758.out","w",stdout);
}
 
template<typename T>void read(T &_){
    _=0; T f=1; char c=getchar();
    for(;!isdigit(c);c=getchar())if(c=='-')f=-1;
    for(;isdigit(c);c=getchar())_=(_<<1)+(_<<3)+(c^'0');
    _*=f;
}
 
const int maxn=1e5+10;
const double inf=1e18;
int n,Lbound,Rbound,s[maxn],sp;
int beg[maxn],to[maxn<<1],las[maxn<<1],cnte=1;
double w[maxn<<1],val[maxn];
int son[maxn],len[maxn],fa[maxn],dfn[maxn],cnt_dfn;
 
void add(int u,int v,int ww){
    las[++cnte]=beg[u]; beg[u]=cnte; to[cnte]=v; w[cnte]=ww;
    las[++cnte]=beg[v]; beg[v]=cnte; to[cnte]=u; w[cnte]=ww;
}
 
void dfs1(int u,int fh){
    fa[u]=fh;
    for(int i=beg[u];i;i=las[i]){
        int v=to[i];
        if(v==fh)continue;
        dfs1(v,u);
        if(len[v]+1>len[u]){
            len[u]=len[v]+1;
            son[u]=v;
            val[u]=w[i];
        }
    }
}
 
void dfs2(int u){
    dfn[u]=++cnt_dfn;
    if(son[u])dfs2(son[u]);
    for(int i=beg[u];i;i=las[i]){
        int v=to[i];
        if(v==fa[u] || v==son[u])continue;
        dfs2(v);
    }
}
 
struct Segment_Tree{
#define mid ((l+r)>>1)
#define lc (o<<1)
#define rc (o<<1|1)
#define lson lc,l,mid
#define rson rc,mid+1,r
    double mx[maxn<<2];
    void build(int o,int l,int r){
        mx[o]=-inf;
        if(l==r)return;
        build(lson),build(rson);
    }
    void update(int o,int l,int r,int p,double x){
        if(l==r)mx[o]=max(mx[o],x);
        else{
            if(p<=mid)update(lson,p,x);
            else update(rson,p,x);
            mx[o]=max(mx[lc],mx[rc]);
        }
    }
    double query(int o,int l,int r,int L,int R){
        if(L>R)return -inf;
        if(L<=l && r<=R)return mx[o];
        else{
            double ret=-inf;
            if(L<=mid)ret=max(ret,query(lson,L,R));
            if(R>=mid+1)ret=max(ret,query(rson,L,R));
            return ret;
        }
    }
#undef mid
}T;
 
bool flag;
 
void solve(int u,double sum,double x){
    if(flag)return;
    T.update(1,1,n,dfn[u],sum);
    if(son[u])solve(son[u],sum+val[u]-x,x);
    for(int i=beg[u];i;i=las[i]){
        int v=to[i];
        if(v==fa[u] || v==son[u])continue;
        solve(v,sum+w[i]-x,x);
        if(flag)return;
        REP(j,dfn[v],dfn[v]+len[v]){
            int dis=j-dfn[v]+1,l=Lbound-dis+dfn[u],r=Rbound-dis+dfn[u];
            l=max(l,dfn[u]),r=min(r,dfn[u]+len[u]);
            if(T.query(1,1,n,j,j)+T.query(1,1,n,l,r)-sum*2>0)flag=true;
            if(flag)return;
        }
        REP(j,dfn[v],dfn[v]+len[v]){
            int p=j-dfn[v]+1+dfn[u];
            T.update(1,1,n,p,T.query(1,1,n,j,j));
        }
    }
    int l=dfn[u]+Lbound,r=min(dfn[u]+len[u],dfn[u]+Rbound);
    if(T.query(1,1,n,l,r)-sum>0)flag=true;
}
 
bool judge(double x){
    T.build(1,1,n);
    flag=0;
    solve(1,0,x);
    return flag;
}
 
int main(){
    //File();
    read(n),read(Lbound),read(Rbound);
    int u,v,ww;
    REP(i,1,n-1)read(u),read(v),read(ww),add(u,v,ww);
    dfs1(1,0);
    dfs2(1);
    double l=0,r=1e6;
    while(r-l>1e-4){
        double mid=(l+r)/2;
        if(judge(mid))l=mid;
        else r=mid;
    }
    printf("%.3lf\n",l);
    return 0;
}

转载于:https://www.cnblogs.com/ylsoi/p/10235560.html

【无人机】基于改进粒子群算法的无人机路径规划研究[和遗传算法、粒子群算法进行比较](Matlab代码实现)内容概要:本文围绕基于改进粒子群算法的无人机路径规划展开研究,重点探讨了在复杂环境中利用改进粒子群算法(PSO)实现无人机三维路径规划的方法,并将其与遗传算法(GA)、标准粒子群算法等传统优化算法进行对比析。研究内容涵盖路径规划的多目标优化、避障策略、航路点约束以及算法收敛性和寻优能力的评估,所有实验均通过Matlab代码实现,提供了完整的仿真验证流程。文章还提到了多种智能优化算法在无人机路径规划中的应用比较,突出了改进PSO在收敛速度和全局寻优方面的优势。; 适合人群:具备一定Matlab编程基础和优化算法知识的研究生、科研人员及从事无人机路径规划、智能优化算法研究的相关技术人员。; 使用场景及目标:①用于无人机在复杂地形或动态环境下的三维路径规划仿真研究;②比较不同智能优化算法(如PSO、GA、蚁群算法、RRT等)在路径规划中的性能差异;③为多目标优化问题提供算法选型和改进思路。; 阅读建议:建议读者结合文中提供的Matlab代码进行实践操作,重点关注算法的参数设置、适应度函数设计及路径约束处理方式,同时可参考文中提到的多种算法对比思路,拓展到其他智能优化算法的研究与改进中。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值