日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

DFS:寻路问题(Roads)

發布時間:2023/12/20 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 DFS:寻路问题(Roads) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

POJ 1724 尋路問題(Roads)

描述

將由數字1到N標記的城市用單行道相連,每條道路都有兩個相關參數:道路長度和需要為道路支付的通行費(用硬幣的數量表示)。鮑勃和愛麗絲過去住在城市1里。在注意到愛麗絲在他們喜歡玩的紙牌游戲中作弊后,鮑勃和她分手了,并決定搬到N城市去。他想盡快趕到那里,但他手頭沒錢。
我們想幫助Bob找到從城市1到城市N的最短路徑,只要他有足夠的錢。

輸入

輸入的第一行包含整數K, 0 <= K <= 10000, Bob在途中可以花費的最大硬幣數。
第二行包含整數N, 2 <= N <= 100,城市總數。
第三行包含整數R, 1 <= R <= 10000,道路總數。
下面的每一行通過指定由單個空白字符分隔的整數S, D, L和T來描述一條路:

  • S為源城市,1 <= S <= N

  • D為目的地城市,1 <= D <= N

  • L是道路長度,1 <= L <= 100

  • T為通行費(用硬幣數量表示),0 <= T <=100

注意:不同的道路可能有相同的源城市和目的地城市。

輸出

輸出唯一 一行應該包含從城市1到城市N的最短路徑的總長度并且到達城市N的總通行費小于或等于K個硬幣。
如果這樣的路徑不存在,則輸出-1。

樣例輸入

5
6
7
1 2 2 3
2 4 3 3
3 4 2 4
1 3 4 1
4 6 2 1
3 5 2 0
5 4 3 2

樣例輸出

11

解題思路

從城市 1開始深度優先遍歷整個圖,找到所有能到達 N 的走法,
選一個最優的。

剪枝操作:

  • 如果當前已經找到的最優路徑長度為L ,那么在繼續搜索的過程中,總長度已經大
    于L的走法,就可以直接放棄,不用走到底了
  • 用minL[k][m] 表示:走到城市k時總過路費為m的條件下,最優路徑的長度。若在
    后續的搜索中,再次走到k時,如果總路費恰好為m,且此時的路徑長度已經超過
    minL[k][m],則不必再走下去了。
  • #include <iostream> #include <vector> using namespace std;int K,N,R;//定義Bob擁有的總錢數,城市總數,道路總數 struct Road {int S, D, L, T; };//定義源城市,目的地城市,道路長度,通行費 vector< vector<Road> > cityMap(110); //鄰接表,cityMap[i]是從點i有路連到的城市集合,此處鄰接表和二維數組差不多 int totalLen, totalCost; //正在走的路徑的長度和花銷 int minLen = 1 << 30; //初始化開始最優路徑的長度為一超級大的數 int visited[110]; //城市是否已經走過的標記 int minL[110][10100]; //minL[i][j]表示從1到i點的,花銷為j的最短路的長度void DFS(int s) //從s開始向N行走 {if(s == N) {minLen = min(minLen,totalLen);return;}//證明已經到達終點并走完全程了,接下來和之前找到的最短路徑進行比較 for(int i = 0;i < cityMap[s].size();i++) {int d = cityMap[s][i].D; //S有路連到Dif(!visited[d]) {int cost = totalCost + cityMap[s][i].T;if(cost > K) continue;//超過最大金額就放棄該條路 if(totalLen + cityMap[s][i].L >= minLen||totalLen + cityMap[s][i].L >= minL[d][cost])continue;//搜索過程中加上下一條路的長度已經大于之前得到的最小路徑就放棄這種走法(與之前搜索結果相比) //或者到達同一目的城市花銷相同但路徑大于之前記錄下的最小路徑就放棄這種走法(與之前搜索某過程相比)//選擇走該條路 totalLen += cityMap[s][i].L;totalCost += cityMap[s][i].T;minL[d][cost] = totalLen;visited[d] = 1;DFS(d);//從d點繼續深度優先搜索 //DFS的意思是從s走到d再接下來的走法,但也可以不走d,在其他走法中可能繞回d//故此走其他點,不走d,要把visited,totalCost,totalLen恢復到走d之前的值 visited[d] = 0;totalCost-= cityMap[s][i].T;totalLen-= cityMap[s][i].L;}} } int main() {cin >>K >> N >> R;//分別輸入Bob擁有的總錢數,城市總數,道路總數 for(int i = 0;i < R; i++) {Road r;cin >> r.S >> r.D >> r.L >> r.T;if( r.S != r.D ) cityMap[r.S].push_back(r);//記錄單向道路 }for(int i = 0;i < 110; i++ )for(int j = 0; j < 10100; j++ )minL[i][j] = 1 << 30;visited[1] = 1;DFS(1);//從第1個城市出發,找到最優路徑后會更新minLen if(minLen < (1 << 30)) cout << minLen << endl;else cout << "-1" << endl; }

    總結

    以上是生活随笔為你收集整理的DFS:寻路问题(Roads)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。