zoukankan      html  css  js  c++  java
  • BZOJ 2763: [JLOI2011]飞行路线

    2763: [JLOI2011]飞行路线
    Time Limit: 10 Sec Memory Limit: 128 MB
    Submit: 4298 Solved: 1655
    [Submit][Status][Discuss]
    Description
    Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司。该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定的价格。Alice和Bob现在要从一个城市沿着航线到达另一个城市,途中可以进行转机。航空公司对他们这次旅行也推出优惠,他们可以免费在最多k种航线上搭乘飞机。那么Alice和Bob这次出行最少花费多少?
    Input
    数据的第一行有三个整数,n,m,k,分别表示城市数,航线数和免费乘坐次数。
    第二行有两个整数,s,t,分别表示他们出行的起点城市编号和终点城市编号。(0<=s,t

    解题思路

    比较简单的dp+最短路,和普通的最短路一样,但是最短路里不写dis,dp[x][i]表示到达x一共用了i次免费。dp[u][i]=min(dp[x][i-1],dp[x][i]+val[i])。
    BZOJ上直接过,结果LUOGU卡spfa!!各种优化卡常结果还是T一个点,最后乖乖的写了dijkstra,上份spfa压压惊。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    
    using namespace std;
    const int MAXN = 10005;
    const int MAXM = 50005;
    const int inf = 0x3f3f3f3f;
    
    inline int rd(){
        register int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)) {x=(x<<1)+(x<<3)+ch-48;ch=getchar();}
        return x*f;
    }
    
    int n,m,K,S,T;
    int head[MAXN],cnt;
    int nxt[MAXM<<1],to[MAXM<<1],val[MAXM<<1];
    int ans=1e9+1,dp[MAXN][15];
    bool vis[MAXN];
    queue<int> q;
    
    inline void add(int bg,int ed,int v){
        to[++cnt]=ed,val[cnt]=v,nxt[cnt]=head[bg],head[bg]=cnt;
    }
    
    inline void spfa(){
        vis[S]=1;q.push(S);dp[S][0]=0;
        while(!q.empty()){
            register int x=q.front();q.pop();
            vis[x]=0;
            for(register int i=head[x];i;i=nxt[i]){
                register int u=to[i];
                if(dp[u][0]>dp[x][0]+val[i]){
                    dp[u][0]=dp[x][0]+val[i];
                    if(!vis[u]){
                        q.push(u);
                        vis[u]=1;
                    }
                }
                for(register int j=1;j<=K;j++){
                    register int now=min(dp[x][j]+val[i],dp[x][j-1]);
                    if(dp[u][j]>now){
                        dp[u][j]=now;
                        if(!vis[u]){
                            q.push(u);
                            vis[u]=1;
                        }
                    }   
                }   
            }
        }
    }
    
    int main(){
        n=rd(),m=rd(),K=rd(),S=rd(),T=rd();S++;T++;
        for(register int i=1;i<=m;i++){
            register int x=rd(),y=rd(),z=rd();x++;y++;
            add(x,y,z);add(y,x,z);
        }
        for(register int i=1;i<=n;i++)
            for(register int j=0;j<=K;j++)
                dp[i][j]=inf;
        spfa();
        for(register int i=0;i<=K;i++)
            ans=dp[T][i]<ans?dp[T][i]:ans;
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    LeetCode链表解题模板
    c++中的new、operator new、placement new
    树的前序、中序、后续、层次遍历的递归和非递归解法
    c++Volatile关键词
    南大算法设计与分析课程OJ答案代码(5)--割点与桥和任务调度问题
    c++右值引用以及使用
    c++选择重载函数
    从4行代码看右值引用
    被遗忘的C结构体打包技术
    南大算法设计与分析课程OJ答案代码(4)--变位词、三数之和
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/9676985.html
Copyright © 2011-2022 走看看