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 };