1. 程式人生 > 其它 >【講解】1030 Travel Plan (30 分)【DFS】_41行程式碼Ac

【講解】1030 Travel Plan (30 分)【DFS】_41行程式碼Ac

技術標籤:PAT甲級# 搜尋# 圖論dfs迪傑斯特拉PATPAT甲級

立志用最少的程式碼做最高效的表達


PAT甲級最優題解——>傳送門


A traveler’s map gives the distances between cities along the highways, together with the cost of each highway. Now you are supposed to write a program to help a traveler to decide the shortest path between his/her starting city and the destination. If such a shortest path is not unique, you are supposed to output the one with the minimum cost, which is guaranteed to be unique.

Input Specification:
Each input file contains one test case. Each case starts with a line containing 4 positive integers N, M, S, and D, where N (≤500) is the number of cities (and hence the cities are numbered from 0 to N−1); M is the number of highways; S and D are the starting and the destination cities, respectively. Then M lines follow, each provides the information of a highway, in the format:


City1 City2 Distance Cost
where the numbers are all integers no more than 500, and are separated by a space.

Output Specification:
For each test case, print in one line the cities along the shortest path from the starting point to the destination, followed by the total distance and the total cost of the path. The numbers must be separated by a space and there must be no extra space at the end of output.

Sample Input:
4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20

Sample Output:
0 2 3 3 40


採用vector做dfs的引數,同時求出最短距離和路徑。 具體邏輯請讀者去程式碼中體會。


#include<bits/stdc++.h>
using namespace std;

int G[510][510], vis[510], cost[510][510];	//地圖、vis陣列、走每條路的花費成本 
int n, m, s_c, d_c;							//城市數、道路數、起點、終點 
vector<int>fin;								//儲存最終路線
int min_dis = 0x3f3f3f3f, min_cost = 0x3f3f3f3f;	//最短距離和花費 

void dfs(int now_dis, int now_cost, vector<int>v) {
	int s = v.back();						//最後一個元素為當前位置 
	
	if(now_dis > min_dis) return;			//剪枝
	 
	if(s == d_c) {							//邊界條件 
		if(now_dis == min_dis) 				//距離相同則比較花費 
			if(now_cost > min_cost) return;
		min_dis = now_dis; 
		min_cost = now_cost;
		fin = v;
		return; 
	}
	for(int i = 0; i < n; i++) 				//逐個點遍歷 
		if(vis[i] == 0 && G[s][i]>0) {		//如果沒訪問過且連通
			v.push_back(i); 				//v陣列壓入該點 
			vis[i] = 1;						//置1表示已訪問 
			dfs(now_dis+G[s][i], now_cost+cost[s][i], v);
			vis[i] = 0;						//回溯 
			v.pop_back();
		} 
}

int main() {
	cin >> n >> m >> s_c >> d_c;
	for(int i = 0; i < m; i++) {
		int c1, c2, dis, val; cin >> c1 >> c2 >> dis >> val;
		G[c1][c2] = G[c2][c1] = dis;		//構建地圖和距離 
		cost[c1][c2] = cost[c2][c1] = val;	//花費 
	}
	
	vector<int>v;  v.push_back(s_c);	//壓入起點 
	vis[s_c] = 1;
	dfs(0, 0, v);	//距離、花費、路線 
	
	for(int i = 0; i < fin.size(); i++) 
		cout << fin[i] << ' ';
	cout << min_dis << ' ' << min_cost << '\n';
	
	return 0;
} 

耗時:

在這裡插入圖片描述