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;
}
posted @ 2018-07-04 16:26  Monster_Qi  阅读(99)  评论(0编辑  收藏  举报