[JLOI2011]飞行路线

本文介绍了一种使用SPFA算法解决飞行路径费用优化问题的方法。通过设定dis[i][j]表示从起点到i点,搭乘了j次飞机的最小费用,利用SPFA算法进行状态转移,最终求得在限定飞行次数内从起点到终点的最小费用。

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

题目链接

算法:

        我们设dis[i][j]表示从t到i的路,搭乘了j次飞机的最小费用,接着我们利用SPFA进行状态的转移即可,

        答案即为max{dis[t][i](0<=i<=k)}。(考虑到k可能大于路径的条数。)

 

Code:

#include<bits/stdc++.h>
#define rep(i,j,k) for(int i=j;i<=k;i++)
using namespace std;
template<typename T> void read(T &num){
    char c=getchar();num=0;T f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){num=(num<<3)+(num<<1)+(c^48);c=getchar();}
    num*=f;
}
template<typename T> void qwq(T x){
    if(x>9)qwq(x/10);
    putchar(x%10+'0');
}
template<typename T> void write(T x){
    if(x<0){x=-x;putchar('-');}
    qwq(x);putchar('\n');
}
template<typename T> void chkmin(T &x,T y){x=x<y?x:y;}

int n,m,k,s,t;
struct wzy{
    int nxt,vertice,w;
}edge[100010];
int head[10010];int len=0;
inline void add_edge(int x,int y,int z){
    edge[++len].nxt=head[x];edge[len].vertice=y;
    edge[len].w=z;head[x]=len;return;
}

priority_queue<pair<int,pair<int,int> > >v;
int dis[10010][15];bool in[10010][15];
inline void SPFA(){
    rep(i,1,n){
        rep(j,0,k){dis[i][j]=INT_MAX;}
    }
    v.push(make_pair(0,make_pair(s,0)));in[s][0]=1;dis[s][0]=0;
    while(!v.empty()){
        int nop1=v.top().second.first;int nop2=v.top().second.second;
        in[nop1][nop2]=0;v.pop();
        for(int i=head[nop1];i;i=edge[i].nxt){
            int temp=edge[i].vertice;
            if(dis[nop1][nop2]+edge[i].w<dis[temp][nop2]){
                dis[temp][nop2]=dis[nop1][nop2]+edge[i].w;
                if(!in[temp][nop2]){
                    v.push(make_pair(-dis[temp][nop2],make_pair(temp,nop2)));
                    in[temp][nop2]=1;
                }
            } 
            
            if(nop2==k)continue;
            if(dis[nop1][nop2]<dis[temp][nop2+1]){
                dis[temp][nop2+1]=dis[nop1][nop2];
                if(!in[temp][nop2+1]){
                    v.push(make_pair(-dis[temp][nop2+1],make_pair(temp,nop2+1)));
                    in[temp][nop2+1]=1;
                }
            }
        }
    }
    return;
}

int main(){
    read(n);read(m);read(k);read(s);read(t);s++;t++; 
    rep(i,1,m){
        int a,b,c;read(a);read(b);read(c);
        add_edge(a+1,b+1,c);add_edge(b+1,a+1,c);
    }
    
    SPFA();
    int ans=INT_MAX;
    rep(i,0,k){chkmin(ans,dis[t][i]);}
    write(ans);
    return 0;
}

 

#include<bits/stdc++.h> using namespace std; const int N=1e4+5; struct node { int to,w; vector<int> way; bool operator <(const node& a)const { return w>a.w; } } e,p; priority_queue<node> q; vector<node> g[N]; vector<int> val(N,INT_MAX); int n,m,k,s,t,u,v,w; bool fl[N]; void dij() {//获取最优路径,从最优路径上减去最大权值边 e.to=s; q.push(e); val[s]=0; while(!q.empty()) { e=q.top(); q.pop(); if(e.to==t) { sort(e.way.begin(),e.way.end()); while(!e.way.empty()&&k) { e.w-=e.way.back(); e.way.pop_back(); k--; } cout<<e.w; return; } if(fl[e.to])continue; fl[e.to]=true; for(node &x:g[e.to]) { if(e.w+x.w<val[x.to]) { p=e; p.to=x.to; p.w+=x.w; p.way.emplace_back(x.w); val[x.to]=e.w+x.w; q.push(p); } } } } int main() { ios::sync_with_stdio(0); cin.tie(0),cout.tie(0); cin>>n>>m>>k>>s>>t; while(m--) { cin>>u>>v>>w; g[u].push_back({v,w}); g[v].push_back({u,w}); } dij(); return 0; }# P4568 [JLOI2011] 飞行路线 ## 题目描述 Alice 和 Bob 现在要乘飞机旅行,他们选择了一家相对便宜的航空公司。该航空公司一共在 $n$ 个城市设有业务,设这些城市分别标记为 $0$ 到 $n-1$,一共有 $m$ 种航线,每种航线连接两个城市,并且航线有一定的价格。 Alice 和 Bob 现在要从一个城市沿着航线到达另一个城市,途中可以进行转机。航空公司对他们这次旅行也推出优惠,他们可以免费在最多 $k$ 种航线上搭乘飞机。那么 Alice 和 Bob 这次出行最少花费多少? ## 输入格式 第一行三个整数 $n,m,k$,分别表示城市数,航线数和免费乘坐次数。 接下来一行两个整数 $s,t$,分别表示他们出行的起点城市编号和终点城市编号。 接下来 $m$ 行,每行三个整数 $a,b,c$,表示存在一种航线,能从城市 $a$ 到达城市 $b$,或从城市 $b$ 到达城市 $a$,价格为 $c$。 ## 输出格式 输出一行一个整数,为最少花费。 ## 输入输出样例 #1 ### 输入 #1 ``` 5 6 1 0 4 0 1 5 1 2 5 2 3 5 3 4 5 2 3 3 0 2 100 ``` ### 输出 #1 ``` 8 ``` ## 说明/提示 #### 数据规模与约定 对于 $30\%$ 的数据,$2 \le n \le 50$,$1 \le m \le 300$,$k=0$。 对于 $50\%$ 的数据,$2 \le n \le 600$,$1 \le m \le 6\times10^3$,$0 \le k \le 1$。 对于 $100\%$ 的数据,$2 \le n \le 10^4$,$1 \le m \le 5\times 10^4$,$0 \le k \le 10$,$0\le s,t,a,b < n$,$a\ne b$,$0\le c\le 10^3$。 另外存在一组 hack 数据。 这道题里我通过记录最大权值边来减去,以此得到结果,但问题是减去back的代码没有执行,样例结果得到13,我需要你分析原因
最新发布
07-31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值