第一届中兴捧月算法大赛迪杰斯特拉派解决方案

本文介绍了一个基于迪杰斯特拉算法的路径搜索问题解决案例,挑战在于寻找满足特定条件的最优路径。案例中,小蚁需在限定条件下从起点到终点收集食物,通过调整迪杰斯特拉算法实现这一目标。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

迪杰斯特拉派初赛赛题

最强大脑中的收官蜂巢迷宫变态级挑战,相信大家都叹为观止!最强大脑收官战打响后,收视率节节攀升,就连蚁后也不时出题难为一下她的子民们。在动物世界中,称得上活地图的,除了蜜蜂,蚂蚁当仁不让。在复杂多变的蚁巢中, 蚂蚁总是能以最快、最高效的方式游历在各个储藏间(存储食物)。今天,她看完最新一期节目,又发布了一项新任务:小蚁同学,我需要玉米库的玉米,再要配点水果,去帮我找来吧。小蚁正准备出发,蚁后又说:哎呀,回来,我还没说完呢,还有若干要求如下:
1.小蚁同学,你需要尽可能以最少的花费拿到食物(附件图中路线上的数值表示每两个储物间的花费);
2.小蚁同学,你最多只能经过9个储藏间拿到食物(包含起止两个节点,多次通过同一节点按重复次数计算);
3.小蚁同学,你必须经过玉米间,水果间(附件图中标绿色节点);
4.别忘了,食蚁兽也在路上活动呢,一旦与食蚁兽相遇,性命危矣!不过小蚁微信群公告已经公布了敌人信息(附件图中标红色路段);
5.最后,千万别忘了,还有两段路是必须经过的,那里有我准备的神秘礼物等着你呢(附件图中标绿色路段)。
这下小蚁犯难了,这和它们平时找食物的集体活动规则不一样嘛,看来这次需要单独行动了。要怎么选路呢?小蚁经过一番苦思冥想,稿纸堆了一摞,啊,终于找到了!亲爱的同学们,你们能否也设计一种通用的路径搜索算法,来应对各种搜索限制条件,找到一条最优路径,顺利完成蚁后布置的任务呢?
注:
1、蚁巢,有若干个储藏间,储藏间之间有诸多路可以到达;
2、节点本身通行无花费;
3、该图为无向图,可以正反两方向通行,两方向都会计费,并且花费相同;
4、起止节点分别为附件图中S点和E点。
5、最优路径:即满足限制条件的路径。

图片附在代码下面了,我的解决方案是对整个图进行一个限制路径的dij,用一个set来判断特殊点的个数,之后对特殊情况进行判断一下就行了。这个解法主要的优点是通用,的确牺牲了一下次优解的情况,只有70分,没拿到区域优胜有点可惜。顺便帮助队友拿到数模校赛一等奖(题目一样)

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
const int maxnum = 100;
const int maxint = 999999;


int dist[maxnum];         //initialize with maxint
int prev[maxnum];
int c[maxnum][maxnum];   //initialize with maxint
int n, line;             // 图的结点数和路径数
set<int> sp_nodes;
bool sp_edge[maxnum][maxnum];
// n -- n nodes
// v -- the source node
// dist[] -- the distance from the ith node to the source node
// prev[] -- the previous node of the ith node
// c[][] -- every two nodes' distance
inline long long fac(int n)
{
    int res=1;
    while(n!=0)
    {
        res*=n;
        n--;
    }
    return res;
}
void Dijkstra_modify(int n, int v)
{
    bool s[maxnum];
    for(int i=0; i<n; i++)
    {
        dist[i] = maxint;
    }

    for(int i=0; i<n; ++i)
    {
        dist[i] = c[v][i];
        s[i] = 0;                         
        if(dist[i] == maxint)
            prev[i] = 0;
        else
            prev[i] = v;
    }

    dist[v] = 0;
    s[v] = 1;

    for(int i=1; i<n; ++i)
    {
        int tmp = maxint;
        int u = v;

        for(int j=0; j<n; ++j)
        {
            if((!s[j]) && dist[j]<tmp)
            {
                u = j;              
                tmp = dist[j];
            }
            // let the special nodes and the current point's edge minimum
            // but if there are mutiple of special node ?
        }

        s[u] = 1;
        // refresh extend
        // no need to change
        for(int j=0; j<n; ++j)
            if((!s[j]) && c[u][j]<maxint)
            {
                int newdist = dist[u] + c[u][j];
                if(newdist < dist[j])
                {
                    dist[j] = newdist;
                    prev[j] = u;
                }
            }
    }
}
void print(int x,int s)
{
    stack<int>q;
    int flag(s);
    while(x!=s)
    {
        q.push(x);
        x=prev[x];
    }
    q.push(s);
    while(q.empty()==0)
    {
        cout<<q.top()<<"->";
        q.pop();
    }
    cout<<"\n";
}

int main()
{
    freopen("graph_in.txt","r",stdin);
    freopen("graph_out.txt","w",stdout);
    int t1= 0,t2=0,t3=0;
    int st_node,tm_node;
    cin>>n>>line;
    for(int i=0; i<=n; i++)
    {
        dist[i]=maxint;
        for(int j=0; j<=n; j++)
        {
            c[i][j]=maxint;
        }
    }
    for(int i=0; i<line; i++)
    {
        cin>>t1>>t2>>t3;
        c[t1][t2] = c[t2][t1] = t3;
    }
    //
    cin>>st_node>>tm_node;
    for(int i=0; i<2; i++)
    {
        cin>>t1;
        sp_nodes.insert(t1);
    }
    for(int i=0; i<2; i++)
    {
        cin>>t1>>t2;
        sp_nodes.insert(t1);
        sp_nodes.insert(t2);
        sp_edge[t1][t2] = sp_edge[t2][t1] = true;

    }
    //edge that unreachable
    cin>>t1>>t2;
    c[t1][t2] = c[t2][t1] = maxint;
    //begin
    vector<int> path,path_p;
    vector<int> sp_nodes_p;
    int cnt=0;
    int ans=maxint;
    int cnt_nodes=0;
    for(set<int>::iterator sit = sp_nodes.begin(); sit!=sp_nodes.end(); sit++)
    {

        sp_nodes_p.push_back(*sit);
    }
    int times=fac(sp_nodes.size());
    for(int i=0; i<times; i++)
    {
        //generate the permutation
        next_permutation(sp_nodes_p.begin(),sp_nodes_p.end());


        path_p.clear();

        vector<int>::iterator it = sp_nodes_p.begin();
        Dijkstra_modify(n,st_node);
        cnt += dist[*it];
        path.push_back(*it);
        //cout<<"st: "<<cnt<<endl;
        bool sp_edge_p[maxnum][maxnum];
        memcpy(sp_edge_p,sp_edge,sizeof(sp_edge_p));

        bool flag = true;

        while(1)
        {

            int tmp=*it;
            it++;
            if(it==sp_nodes_p.end())
            {
                break;
            }
            if(sp_edge_p[tmp][*it])
            {
                //cout<<"hit : "<<tmp<<"->"<<*it<<" ";
                sp_edge_p[*it][tmp] = false;
                //refresh the temp
                cnt += c[tmp][*it];
                //cout<<c[tmp][*it]<<endl;
                path_p.push_back(tmp);
                path_p.push_back(*it);
            }
            else
            {
                for(int j=0; j<n; j++)
                {
                    if(sp_edge_p[tmp][j])
                    {
                        flag = false;
                        break;
                    }
                }
                if(!flag)
                {
                    break;
                }
                Dijkstra_modify(n,tmp);
                cnt += dist[*it];
                //refresh the temp
                //cout<<"short : "<<tmp<<"->"<<*it<<" : ";
                //print(*it,tmp);
                stack<int> q;
                int tmp2=*it;
                while(tmp2!=tmp)
                {
                    q.push(tmp2);
                    tmp2=prev[tmp2];
                }
                while(q.empty()==0)
                {
                    path_p.push_back(q.top());
                    q.pop();
                }
                //cout<<dist[*it]<<endl;
            }
        }
        if(!flag)
        {
            //cout<<"pass"<<endl;
            cnt=0;
            continue;
        }

        int e=sp_nodes_p[sp_nodes_p.size()-1];
        Dijkstra_modify(n,e);
        cnt+=dist[tm_node];
        //cout<<"Path :";
        int judge=st_node;

        //cout<<tm_node<<endl;
        //cout<<"tm :"<<dist[tm_node]<<endl;
        if(ans > cnt)
        {
            path.clear();
            ans = cnt;
            for(vector<int>::iterator pit =path_p.begin(); pit!=path_p.end(); pit++)
            {
                if(judge == *pit) continue;
                judge=*pit;
                path.push_back(*pit);
            }
            cnt_nodes=path.size();
        }
        cnt=0;
    }
    cout<<"distance :"<<ans<<endl;
    int judge = st_node;
    cout<<"path :"<<st_node<<"->";
    for(int i=0; i<cnt_nodes; i++)
    {
        if(judge == path[i]) continue;
        cout<<path[i]<<"->";
        judge=path[i];
    }
    cout<<tm_node<<endl;
    if(cnt_nodes>6)
    {
        cout<<"No optimal solution"<<endl;
    }
    else
    {
        cout<<"The optimal solution:"<<endl;
    }
    cout<<"number of nodes :"<<cnt_nodes+2<<endl;
    return 0;
}
拍贷“魔镜风控系统”从平均 拍贷“魔镜风控系统”从平均 拍贷“魔镜风控系统”从平均 拍贷“魔镜风控系统”从平均 拍贷“魔镜风控系统”从平均 拍贷“魔镜风控系统”从平均 拍贷“魔镜风控系统”从平均 拍贷“魔镜风控系统”从平均 400 个数据维度评估用户当前的信状态,给每借款 个数据维度评估用户当前的信状态,给每借款 个数据维度评估用户当前的信状态,给每借款 个数据维度评估用户当前的信状态,给每借款 个数据维度评估用户当前的信状态,给每借款 个数据维度评估用户当前的信状态,给每借款 个数据维度评估用户当前的信状态,给每借款 个数据维度评估用户当前的信状态,给每借款 个数据维度评估用户当前的信状态,给每借款 个数据维度评估用户当前的信状态,给每借款 人打出当前状态的 信用分,在此基础上再结合新发标息对于每个人打出当前状态的 信用分,在此基础上再结合新发标息对于每个人打出当前状态的 信用分,在此基础上再结合新发标息对于每个人打出当前状态的 信用分,在此基础上再结合新发标息对于每个人打出当前状态的 信用分,在此基础上再结合新发标息对于每个人打出当前状态的 信用分,在此基础上再结合新发标息对于每个人打出当前状态的 信用分,在此基础上再结合新发标息对于每个人打出当前状态的 信用分,在此基础上再结合新发标息对于每个人打出当前状态的 信用分,在此基础上再结合新发标息对于每个人打出当前状态的 信用分,在此基础上再结合新发标息对于每个人打出当前状态的 信用分,在此基础上再结合新发标息对于每个人打出当前状态的 信用分,在此基础上再结合新发标息对于每个人打出当前状态的 信用分,在此基础上再结合新发标息对于每个人打出当前状态的 信用分,在此基础上再结合新发标息对于每个人打出当前状态的 信用分,在此基础上再结合新发标息对于每个人打出当前状态的 信用分,在此基础上再结合新发标息对于每个人打出当前状态的 信用分,在此基础上再结合新发标息对于每个6个内逾 个内逾 期率的预测 ,为投资人提供关键决策依据。本次竞赛目标是根用户历史行数来期率的预测 ,为投资人提供关键决策依据。本次竞赛目标是根用户历史行数来期率的预测 ,为投资人提供关键决策依据。本次竞赛目标是根用户历史行数来期率的预测 ,为投资人提供关键决策依据。本次竞赛目标是根用户历史行数来期率的预测 ,为投资人提供关键决策依据。本次竞赛目标是根用户历史行数来期率的预测 ,为投资人提供关键决策依据。本次竞赛目标是根用户历史行数来期率的预测 ,为投资人提供关键决策依据。本次竞赛目标是根用户历史行数来期率的预测 ,为投资人提供关键决策依据。本次竞赛目标是根用户历史行数来期率的预测 ,为投资人提供关键决策依据。本次竞赛目标是根用户历史行数来期率的预测 ,为投资人提供关键决策依据。本次竞赛目标是根用户历史行数来期率的预测 ,为投资人提供关键决策依据。本次竞赛目标是根用户历史行数来期率的预测 ,为投资人提供关键决策依据。本次竞赛目标是根用户历史行数来期率的预测 ,为投资人提供关键决策依据。本次竞赛目标是根用户历史行数来期率的预测 ,为投资人提供关键决策依据。本次竞赛目标是根用户历史行数来期率的预测 ,为投资人提供关键决策依据。本次竞赛目标是根用户历史行数来期率的预测 ,为投资人提供关键决策依据。本次竞赛目标是根用户历史行数来期率的预测 ,为投资人提供关键决策依据。本次竞赛目标是根用户历史行数来期率的预测 ,为投资人提供关键决策依据。本次竞赛目标是根用户历史行数来期率的预测 ,为投资人提供关键决策依据。本次竞赛目标是根用户历史行数来用户在未来 用户在未来 用户在未来 6个内是否会逾期还款的概率。 个内是否会逾期还款的概率。 个内是否会逾期还款的概率。 个内是否会逾期还款的概率。 个内是否会逾期还款的概率。 个内是否会逾期还款的概率。 个内是否会逾期还款的概率。 问题转换成 问题转换成 问题转换成 2分类问题,评估指标为 分类问题,评估指标为 分类问题,评估指标为 分类问题,评估指标为 分类问题,评估指标为 分类问题,评估指标为 分类问题,评估指标为 AUC ,从 Master Master Master,LogInfoLogInfo LogInfo ,UpdateInfo UpdateInfo UpdateInfo 表中构建 表中构建 特征,考虑评估指标为 特征,考虑评估指标为 特征,考虑评估指标为 特征,考虑评估指标为 特征,考虑评估指标为 AUC AUC,其本质是排序优化问题,所以我们在模型顶层融合也使用基于 ,其本质是排序优化问题所以我们在模型顶层融合也使用基于 ,其本质是排序优化问题所以我们在模型顶层融合也使用基于 ,其本质是排序优化问题所以我们在模型顶层融合也使用基于 ,其本质是排序优化问题所以我们在模型顶层融合也使用基于 ,其本质是排序优化问题所以我们在模型顶层融合也使用基于 ,其本质是排序优化问题所以我们在模型顶层融合也使用基于 ,其本质是排序优化问题所以我们在模型顶层融合也使用基于 ,其本质是排序优化问题所以我们在模型顶层融合也使用基于 ,其本质是排序优化问题所以我们在模型顶层融合也使用基于 ,其本质是排序优化问题所以我们在模型顶层融合也使用基于 ,其本质是排序优化问题所以我们在模型顶层融合也使用基于 ,其本质是排序优化问题所以我们在模型顶层融合也使用基于 ,其本质是排序优化问题所以我们在模型顶层融合也使用基于 ,其本质是排序优化问题所以我们在模型顶层融合也使用基于 排序优化的 排序优化的 排序优化的 RANK_AVG RANK_AVG RANK_AVG融合方法。 融合方法。 融
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值