zoukankan      html  css  js  c++  java
  • HYSBZ

    题目:

    Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司。该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定的价格。Alice和Bob现在要从一个城市沿着航线到达另一个城市,途中可以进行转机。航空公司对他们这次旅行也推出优惠,他们可以免费在最多k种航线上搭乘飞机。那么Alice和Bob这次出行最少花费多少?

    思路:

    典型的分层图求最短路问题,这类问题一般适用于我们要对图中的某些边的权进行变换的情况,当然变换的次数要很小才行。

    d[u][j]表示到达u点已经免费乘坐了j次航线的最短距离。在套一个裸的迪杰斯特拉算法就可以了。

    代码:

    //#include <bits/stdc++.h>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <queue>
    #define MAX 1000000000
    #define inf 0x3f3f3f3f
    #define FRE() freopen("in.txt","r",stdin)
    
    using namespace std;
    typedef long long ll;
    const int maxn = 10005;
    int n,m,k,s,t;
    int d[maxn][15];
    struct Edge
    {
        int to,c;
    };
    vector<Edge> mp[maxn];
    struct Node
    {
        int u,k,d;
        bool operator<(const Node& rhs)const{
            return d>rhs.d;
        }
    };
    
    void Dij()
    {
        for(int i=0; i<=k; i++) d[s][i] = 0;
        priority_queue<Node> que;
        que.push(Node{s,0,0});
        while(!que.empty())
        {
            Node u = que.top();
            que.pop();
            if(u.d>d[u.u][u.k]) continue;
            for(int i=0; i<mp[u.u].size(); i++)
            {
                Edge e = mp[u.u][i];//可以将这里的分层图看做是dp来理解
                if(u.d+e.c<d[e.to][u.k])//不乘坐免费的情况
                {
                    d[e.to][u.k] = u.d+e.c;
                    que.push(Node{e.to,u.k,u.d+e.c});
                }
                if(u.k+1<=k && d[e.to][u.k+1]>d[u.u][u.k])//免费乘坐的情况
                {
                    d[e.to][u.k+1] = d[u.u][u.k];
                    que.push(Node{e.to,u.k+1,d[u.u][u.k]});
                }
            }
        }
        return ;
    }
    
    
    int main()
    {
        //FRE();
        memset(d,inf,sizeof(d));
        scanf("%d%d%d",&n,&m,&k);
        scanf("%d%d",&s,&t);
        for(int i=0; i<m; i++)
        {
            int u,v,c;
            scanf("%d%d%d",&u,&v,&c);
            mp[u].push_back(Edge{v,c});
            mp[v].push_back(Edge{u,c});
        }
        Dij();
        int ans = inf;
        for(int i=0; i<=k; i++)
        {
            ans = min(ans,d[t][i]);
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    【技术分享】sphinx的--rotate运行机制
    【技术分享】JQuery Mobile转场分析
    【游戏小心得】火焰纹章的核心精髓
    【新手向】键盘常用 ASCII 码
    【基础知识】进程与线程的区别
    【巧知识】js ==与===区别(两个等号与三个等号)
    python: HTML之 鼠标放上去下拉项字体显示不同颜色
    python:页面布局 后台管理页面之常用布局
    python :页面布局 ,后台管理页面之左侧菜单跟着滚动条动
    python : HTML+CSS (左侧菜单)
  • 原文地址:https://www.cnblogs.com/sykline/p/10498852.html
Copyright © 2011-2022 走看看