787. Cheapest Flights Within K Stops

仅供自己学习

 

思路:

深搜和广搜都是能做的,但是需要进行剪枝。剪枝条件,如果该点访问过了就不对这个点继续DFS,如果K<0了且没到达目的点就返回不继续DFS,  如果当前的花费+新节点的花费大于之前的花费也返回不继续DFS。

DFS:

 1 class Solution {
 2 public:
 3     int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int K) {
 4         unordered_map<int,vector<vector<int>>> edge;
 5         unordered_set<int> visited{{src}};
 6         int res=INT_MAX;
 7         for(const auto& ex:flights){
 8             edge[ex[0]].push_back({ex[1],ex[2]});
 9         }
10         DFS(edge,src,dst,K,res,0,visited);
11         return (res==INT_MAX)? -1:res;
12     }
13 
14     void DFS(unordered_map<int,vector<vector<int>>>& edge,int cur,int dst,int K,int& res,int out,unordered_set<int>& visited){
15         if(cur==dst){
16             res=out;
17             return;
18         }
19         if(K<0) return;
20         for(const auto& flight:edge[cur]){
21             if(visited.count(flight[0])||out+flight[1]>res) continue;
22             visited.insert(flight[0]);
23             DFS(edge,flight[0],dst,K-1,res,out+flight[1],visited);
24             visited.erase(flight[0]);
25         }
26     }
27 };

 

这里有个问题,因为DFS不是return res,所以要传 res 的reference进入函数,这样才能改变参数。

 

DFS代码:

 1 class Solution {
 2 public:
 3     int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int K) {
 4         unordered_map<int,vector<vector<int>>> edge;
 5         queue<vector<int>> q{{{src,0}}};  //第一个是当前节点,第二个是达到当前节点的花费总和
 6         int res=INT_MAX,cnt=0;
 7         for(const auto& ex:flights){
 8             edge[ex[0]].push_back({ex[1],ex[2]});
 9         }
10         while(!q.empty()){
11             for(int i=q.size();i>0;--i){
12                 auto t=q.front();
13                 q.pop();
14                 if(t[0]==dst) res=min(res,t[1]);
15                 for(const auto& a:edge[t[0]]){
16                     if(t[1]+a[1]>res) continue;
17                     q.push({a[0],t[1]+a[1]});
18                 }
19             }
20             if(cnt++>K) break;
21         }
22         return (res==INT_MAX)? -1:res;
23     }
24 };

 

Bellman-ford:

根据伪代码及递归式

 

递归式为:

 

 伪代码:

 

可得到代码:

这是用了二维数组的,空间复杂度为O(n^2)

 1 class Solution {
 2 public:
 3     int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int K) {
 4        vector<vector<int>> dp(K+2,vector<int>(n,1e9));
 5        dp[0][src] = 0;
 6        for(int i=1;i<=K+1;++i){
 7            dp[i][src]=0;
 8            for(auto& x:flights){
 9                dp[i][x[1]] = min(dp[i][x[1]],dp[i-1][x[0]]+x[2]);
10            }  //该递归式,如果有其他跳数跳到该点的距离更小就更新,i为跳数
11        }
12        return (dp[K+1][dst]>=1e9) ? -1:dp[K+1][dst];
13     }
14 };

 

 下面是一维数组的

伪代码为:

 

 代码:

 1 class Solution {
 2 public:
 3     int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int K) {
 4        vector<int> dp(n,1e9);
 5        dp[src] = 0;
 6        for(int i=0;i<=K;++i){
 7            vector<int> temp=dp;
 8            for(auto& x:flights){
 9                temp[x[1]] = min(temp[x[1]],dp[x[0]]+x[2]);
10            }
11            dp = temp;
12        }
13        return (dp[dst]>=1e9) ? -1:dp[dst];
14     }
15 };

 

posted @ 2021-03-05 20:49  Mrsdwang  阅读(58)  评论(0编辑  收藏  举报