专栏文章

P4568 [JLOI2011] 飞行路线 题解

P4568题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mipkz69v
此快照首次捕获于
2025/12/03 13:42
3 个月前
此快照最后确认于
2025/12/03 13:42
3 个月前
查看原文
题意: 有 n 个点,由 m 条双向边连接。城市 aia_i 与城市 bib_i 之间有一条双向边,费用为 c 。共有 k 次免费机会。求最小费用
听起来就挺像DP
思路:由题面求最小可知,需要用到DP和最短路。鉴于还要搜索,加一个bfs。
C
#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll n,m,k,s,t,f[100001][21];
struct edge{
	ll nt,to,vl;
}p[1000001];
ll hd[1000001],nm;
void ad(ll x,ll y,ll z){
	p[++nm].nt=hd[x];
	p[nm].to=y;
	p[nm].vl=z;
	hd[x]=nm;
}
//建图ing
struct vs{
	ll x,vl;
	vs(ll a,ll b){
		x=a;
		vl=b;
	}
	bool operator <(const vs b) const{
        return vl>b.vl;
    }
};
//dfs ing
priority_queue<vs> q;
void djstl(){
	for(ll i=0;i<=k;i++)
		f[s][i]=0;
	for(ll i=0;i<=k;i++){
		q.push(vs(s,0));
		while(!q.empty()){
			vs u=q.top();
			q.pop();
			if(u.vl>f[u.x][i]) continue;
			for(ll j=hd[u.x];j;j=p[j].nt){
				ll v=p[j].to;
				bool bl=0;
				if(i)
					if(f[v][i]>f[u.x][i-1]){
						f[v][i]=f[u.x][i-1];
						bl=1;
					}
				if(f[v][i]>f[u.x][i]+p[j].vl){
					f[v][i]=f[u.x][i]+p[j].vl;
					bl=1;
				}
				if(bl) q.push(vs(v,f[v][i]));
			}
		}
	}
}
//DPing
int main(){
	cin>>n>>m>>k>>s>>t;
	for(ll i=1;i<=m;i++){
		ll x,y,z;
		cin>>x>>y>>z;
		ad(x,y,z);
		ad(y,x,z);
	}
	for(ll i=0;i<n;i++)
		for(ll j=0;j<=k;j++)
			f[i][j]=1e9;
	djstl();
	cout<<f[t][k];
	return 0;
}
//没了
此代码成分复杂,没有危险,可放心使用。

评论

0 条评论,欢迎与作者交流。

正在加载评论...