1. 程式人生 > >HYSBZ - 2763 飛行路線(分層圖最短路線)

HYSBZ - 2763 飛行路線(分層圖最短路線)

pan n) 進行 color 思路 std namespace bool ostream

題目:

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\n",ans); return 0; }

HYSBZ - 2763 飛行路線(分層圖最短路線)