HDU 6166 Senior Pan 2017多校第9场

本文介绍了一种利用二进制优化方法求解特定点集间最短路径问题的有效算法。通过将点集内的点按二进制位划分到两个子集中,并对每个划分进行最短路径计算,从而减少了不必要的计算过程。最终通过20次二进制位的枚举实现了高效求解。
  • 题意:

    • 给定一个带权有向图,一个点集(k个点,无相同点)
    • 求点集元素间的最短距离
  • 规模:

    • 1<=n,m,k<=1e5
    • 1<=w<=1e5
  • 类型:

    • 图论,最短路
    • 二进制优化
  • 分析:

    • 考虑最暴力的做法,枚举点集里所有点,求单源最短路,复杂度k*nlogm,当然是过不了
    • 这里我们优化求最短路的次数
    • 纯暴力的做法很容易看出来有多余的计算

    • 全集合最短路有两个端点,分别位于两个点集S,T。

    • 如果我们能将集合内任意两点,分割到两个点集里,求最短路,那么一定包含全集合的最短路
    • 减少分割次数就能优化掉k
    • 任意两点的序号的二进制不同,一定有一位二进制位能将两点划分到两个集合
    • 枚举二进制位来划分最多20次
  • 时间复杂度&&优化:

    • O(20*nlogm)
  • 代码:

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
const int MAXN=1e5+10;
const int MAXM=1e5+10;
const int INF=0x3fff3fff;


int n,m,k;
int kk[MAXN];
int dist[MAXN];

struct Edge{
    int v,w;
};
vector<Edge> edge[MAXN];
void addedge(int u,int v,int w){
    Edge x;x.v=v;x.w=w;
    edge[u].push_back(x);
}

struct node{
    int x;
    int dis;
    node(int _x=0,int _dis=0):x(_x),dis(_dis){}
    bool operator < (const node &other)const{
        if(dis!=other.dis)return dis>other.dis;
        return x-other.x;
    }
};

priority_queue<node> q;
int vis[MAXN];

int dijstra(){
    int res;
    while(!q.empty()){
        node now=q.top();
        q.pop();
        int u=now.x;
        int dis=now.dis;
        if(vis[u])return dis;
        //vis[u]=1;  //多了这行会wa,毕竟不是单源最短路,目标点也是固定的点集
        for(int i=0;i<edge[u].size();i++){
            int v=edge[u][i].v;
            int w=edge[u][i].w;
            if(dist[v]>dist[u]+w){
                dist[v]=dist[u]+w;
                q.push(node(v,dist[v]));
            }
        }
    }
    return INF;
}

void init(){
    for(int i=0;i<MAXN;i++)dist[i]=INF;
    memset(vis,0,sizeof(vis));
    while(!q.empty())q.pop();

}

int solve(){
    int res=INF;
    for(int i=0;i<20;i++){
        init();
        for(int j=0;j<k;j++){
            int v=kk[j];
            if(v&(1<<i)){
                q.push(node(v,0));
                dist[v]=0;
            }
            else {
                vis[v]=1;
            }
        }
        res=min(res,dijstra());
        init();
        for(int j=0;j<k;j++){
            int v=kk[j];
            if(!( v&(1<<i) )){
                q.push(node(v,0));
                dist[v]=0;
            }
            else {
                vis[v]=1;
            }
        }
        res=min(res,dijstra());

    }
    return res;
}

int main()
{
    int T;
    cin>>T;
    int kase=0;
    while(T--){
        scanf("%d%d",&n,&m);
        for(int i=0;i<MAXN;i++)edge[i].clear();
        for(int i=0;i<m;i++){
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            addedge(u,v,w);
        }
        scanf("%d",&k);
        for(int i=0;i<k;i++)scanf("%d",&kk[i]);
        printf("Case #%d: %d\n", ++kase,solve());
    }

    return 0;
}
内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文章详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函数优化、图像分割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值