# 01 第一个容易想到的dfs (超时)

class Solution {
public:

int res=INT_MAX;
vector<vector<int>>G;
// dfs(cur,total,layer) 表示从src点开始到达cur ,cur(在第layer 层)
void dfs(int cur,int total,int layer,vector<vector<int>> & fee,int K,int dst){
if(layer>K+1) return;
if(cur==dst){
res=min(res,total);
cout<<res<<endl;
return;
}
for(auto v:G[cur]){
dfs(v,total+fee[cur][v],layer+1,fee,K,dst);
}
}
int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int K) {
G.resize(n);
vector<vector<int>>fee(n,vector<int>(n,-1));
for( auto e:flights){
G[e[0]].push_back(e[1]);
fee[e[0]][e[1]]=e[2];
}
dfs(src,0,0,fee,K,dst);
return  res==INT_MAX? -1:res;
}
};


# 02 由上面得到下面的逆向dfs(超时)

// dfs(int cur,int layer,vector<vector<int>> & fee,int K,int dst)
//表示从cur 到dst的最小费用,当前cur位于第layer 层.
//因此只需要返回dfs(0,0,fee,K,dst)

class Solution {
public:

vector<vector<int>>G;
long long dfs(int cur,int layer,vector<vector<int>> & fee,int K,int dst){
if(layer>K+1) return INT_MAX;
if(cur==dst){
return 0;
}
long long res=INT_MAX;
for(auto v:G[cur]){

res=min(fee[cur][v]+dfs(v,layer+1,fee,K,dst),res);
}
return res;
}

int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int K) {
G.resize(n);
vector<vector<int>>fee(n,vector<int>(n,-1));
for( auto e:flights){
G[e[0]].push_back(e[1]);
fee[e[0]][e[1]]=e[2];
}
int ans=dfs(src,0,fee,K,dst);
return  ans==INT_MAX? -1:ans;
}
};


# 03 对上述的逆向dfs 做记忆化,可通过

class Solution {
public:
vector<vector<int>>G;
//dfs(cur,layer,dst) 表示cur(在layer层)到dst所需的最小花费,
//记忆化搜索mem[cur][layer]表示从cur(在layer层)到dst所需的最小花费
long long dfs(int cur,int layer,vector<vector<int>> & fee,int K,int dst,vector<vector<int>> & mem){
if(layer>K+1) return INT_MAX;
if(cur==dst){
mem[cur][layer]=0;
return 0;
}
if(mem[cur][layer]!=INT_MAX) return mem[cur][layer];
long long res=INT_MAX;
for(auto v:G[cur]){
res=min(fee[cur][v]+dfs(v,layer+1,fee,K,dst,mem),res);
}
mem[cur][layer]=res;
return res;
}
int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int K) {
G.resize(n);
vector<vector<int>>fee(n,vector<int>(n,-1));
for( auto e:flights){
G[e[0]].push_back(e[1]);
fee[e[0]][e[1]]=e[2];
}
vector<vector<int>>  mem(n,vector<int>(K+2,INT_MAX));
int ans=dfs(src,0,fee,K,dst,mem);
return  ans==INT_MAX? -1:ans;
}
};


### 05 正向dfs


class Solution {
public:
vector<vector<int>>Parents;
//dfs(cur,layer,dst) 表示从src到cur(在layer层)所需的最小花费,
// 记忆化递规 mem[cur][k-1]
long long dfs(int cur,vector<vector<int>> & fee,int K,int src){
if(K<0) return INT_MAX;
if(cur==src){
return 0;
}
long long res=INT_MAX;
for(auto v:Parents[cur]){
res=min(fee[v][cur]+dfs(v,fee,K-1,src),res);
}
return res;
}

int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int K) {
Parents.resize(n);
vector<vector<int>>fee(n,vector<int>(n,-1));
for( auto e:flights){
// G[e[0]].push_back(e[1]);
Parents[e[1]].push_back(e[0]);
fee[e[0]][e[1]]=e[2];
}
int ans=dfs(dst,fee,K+1,src);
return  ans==INT_MAX? -1:ans;
}
};



# 06 对上面的做记忆化

class Solution {
public:

vector<vector<int>>Parents;
//dfs(cur,layer,dst) 表示从src到cur(在layer层)所需的最小花费,
// 记忆化递规 mem[cur][k-1]
long long dfs(int cur,vector<vector<int>> & fee,int K,int src,vector<vector<int>> & mem){
if(K<0) return INT_MAX;
if(cur==src){
mem[cur][K]=0;
return 0;
}
if(mem[cur][K]!=INT_MAX) return mem[cur][K];
long long res=INT_MAX;
for(auto v:Parents[cur]){
res=min(fee[v][cur]+dfs(v,fee,K-1,src,mem),res);
}
mem[cur][K]=res;
return res;
}

int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int K) {
Parents.resize(n);
vector<vector<int>>fee(n,vector<int>(n,-1));
// vector<vector<int>> & fee
for( auto e:flights){
// G[e[0]].push_back(e[1]);
Parents[e[1]].push_back(e[0]);
fee[e[0]][e[1]]=e[2];
}
vector<vector<int>>  mem(n,vector<int>(K+2,INT_MAX));
int ans=dfs(dst,fee,K+1,src,mem);
return  ans==INT_MAX? -1:ans;
}
};


# 07 由上面得正向DP


class Solution {
public:
// dp[cur][layer]表示从src到cur(在layer层)所需的最小花费,
vector<vector<int>>Parents;
int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int K) {
Parents.resize(n);
vector<vector<int>>fee(n,vector<int>(n,-1));
for( auto e:flights){
Parents[e[1]].push_back(e[0]);
fee[e[0]][e[1]]=e[2];
}
vector<vector<long long>>  dp(n,vector<long long >(K+2,INT_MAX));
for(int k=0;k<=K+1;k++)
dp[src][k]=0;
int cur;
for(int k=1;k<=K+1;k++){
for( cur=0;cur<n;cur++){
if(dp[cur][k]!=INT_MAX) continue;
for(auto v:Parents[cur]){
dp[cur][k]=min((fee[v][cur]+dp[v][k-1]),dp[cur][k]);
}

}
}
int ans=dp[dst][K+1];
return  ans==INT_MAX? -1:ans;
}
};


# 08 bfs 超时

class Solution {
public:
int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int K) {
vector<vector<int>>G(n);
vector<vector<int>>fee(n,vector<int>(n,-1));
for( auto e:flights){
G[e[0]].push_back(e[1]);
fee[e[0]][e[1]]=e[2];
}
queue<vector<int>>q;
q.push({src,0,0});// (cur,total,layer); 表示当前在cur 节点，第layer 层，累积和为total
int res=INT_MAX;
while(!q.empty()){
auto top=q.front();
int cur=top[0];
int total=top[1];
int layer=top[2];
q.pop();
if(layer>K) break;
for( auto v:G[cur]){
if(v==dst) res=min(res,total+fee[cur][v]);
q.push({v,total+fee[cur][v],layer+1});
}
}
return  res==INT_MAX? -1:res;
}
};



# 09bfs+优先队列

bool cmp(const vector<int> &a,const vector<int> &b){
return a[1]>b[1];
}
class Solution {
public:
int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int K) {
vector<vector<int>>G(n);
vector<vector<int>>fee(n,vector<int>(n,-1));
for( auto e:flights){
G[e[0]].push_back(e[1]);
fee[e[0]][e[1]]=e[2];
}
priority_queue<vector<int>,vector<vector<int>>,decltype (cmp) *>q(cmp);
q.push({src,0,0});// (cur,total,layer);
int res=INT_MAX;
while(!q.empty()){
auto top=q.top();
int cur=top[0];
int total=top[1];
int layer=top[2];
if(cur==dst) { return total; break;}

q.pop();
// cout<<cur<<endl;
if(layer>K) continue;
for( auto v:G[cur]){

q.push({v,total+fee[cur][v],layer+1});
}
}
return  res==INT_MAX? -1:res;
}
};


©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客