Tuan trang mat
quoc14
c_cpp
22 days ago
4.5 kB
3
Indexable
Never
Backtrack
Level 4 Tuần Trăng Mật (2 dong endl) Tuần trăng mật Đám cưới anh Uranus diễn ra rất vui vẻ, chỉ có Tomoky là có chút hậm hực. Sau đám cưới, anh Uranus muốn đi tuần trăng mật ở thành phố Đà Lạt xinh đẹp. Thành phố Đà Lạt gồm n điểm du lịch trọng điểm, được đánh số từ 1 tới n. Hệ thống giao thông trong vùng gồm m (m <= n*(n-1)) tuyến đường một chiều khác nhau, tuyến đường thứ j (j = 1,2,…m) cho phép đi từ địa điểm u_j tới địa điểm v_j với chi phí đi lại là số nguyên dương c(u_j, v_j). Anh Uranus muốn xuất phát từ điểm du lịch 1 và đi thăm k địa điểm du lịch s_1, s_2, …, s_k (khác địa điểm 1) và sau đó quay về địa điểm xuất phát 1 với tổng chi phí là nhỏ nhất. Cho thông tin về hệ thống giao thông và k địa điểm du lịch s_1, s_2, …, s_k. Hãy giúp anh Uranus xây dựng một hành trình du lịch xuất phát từ địa điểm du lịch 1 và đi thăm k địa điểm s_1, s_2, …, s_k sau đó quay về địa điểm du lịch 1 với tổng chi phí nhỏ nhất. Input • Dòng đầu tiên chứa số nguyên dương T là số bộ test. Mỗi bộ test gồm: • Dòng thứ nhất chứa 3 số nguyên n, m, k (n <= 1000 và k <= 15). • Dòng thứ hai chứa k số nguyên dương s_1, s_2, …, s_k. • Dòng thứ j trong m dòng tiếp theo chứa 3 số nguyên dương u_j, v_j, c(u_j, v_j) cho biết thông tiên về tuyến đường thứ j. Biết rằng u_j luôn khác v_j, và c(u_j, v_j) <= 10^9. Output In ra một số nguyên là tổng chi phí nhỏ nhất tìm được. Nếu không tìm được một hành trình du lịch nào, in ra số -1. Example Input: 1 6 8 2 2 5 1 2 4 2 4 2 4 3 3 3 1 4 4 1 5 3 5 5 5 3 1 5 6 7 Output: Case #1 19 Case #2 57 Case #1 27 Case #2 57 Case #3 58 Case #4 -1 Case #5 104 Case #6 4381981 Case #7 -1 #include <iostream> #include <time.h> using namespace std; int oo = 2000000000; long long ooll = 9000000000000000000; int T, n, m, k; long long result; int mp[1001][1001], arr[16], vs[1001]; long long dd[1001], mm[1001][1001]; bool checkVs(){ for(int i = 0; i <= k; i++){ if(vs[arr[i]] == 0) return false; } return true; } void resetVs(){ for(int i = 1; i <= n; i++){ vs[i] = 0; dd[i] = ooll; } } void dijkstra(int index){ resetVs(); dd[index] = 0; while(true){ long long minV = ooll; int minI = -1; for(int i = 1; i <= n; i++){ if( !vs[i] && dd[i] < minV){ minV = dd[i], minI = i; } } vs[minI]++; mm[index][minI] = minV; if(minV == ooll) return; if(checkVs()){ break; } // update value for(int i = 1; i <= n; i++){ if(vs[i] == 0 && mp[minI][i] != oo && dd[minI] + mp[minI][i] < dd[i]){ dd[i] = dd[minI] + mp[minI][i]; } } } } void backtrack(int index, int curr, long long cost){ if(cost >= result) return; if(index == k){ if(mm[arr[curr]][1] != -1){ if(cost + mm[arr[curr]][1] < result) result = cost + mm[arr[curr]][1]; } return; } for(int i = 1; i <= k; i++){ if(!vs[arr[i]]){ vs[arr[i]]++; if(mm[arr[curr]][arr[i]] != -1){ backtrack(index + 1, i, cost + mm[arr[curr]][arr[i]]); } vs[arr[i]]--; } } } int main(){ // read input freopen("input.txt", "r", stdin); //calc time clock_t tStart, tStop; tStart = clock(); cin >> T; for(int tc = 1; tc <= T; tc++){ // input and initial cin >> n >> m >> k; for(int i = 1; i <= k; i++){ cin >> arr[i]; } for(int i = 1; i <= n; i++){ for(int j = 1; j <= n; j++){ mp[i][j] = oo; mm[i][j] = -1; } } for(int i = 1; i <= m; i++){ int a, b; cin >> a >> b; cin >> mp[a][b]; } arr[0] = 1; result = ooll; // solve problem for(int i = 0; i <= k; i++){ dijkstra(arr[i]); } resetVs(); vs[1]++; backtrack(0, 0, 0); // output cout << "Case #" << tc << endl << ((result != ooll)? (result) : -1) << endl << endl; } //calc time tStop = clock(); cout.setf(ios::fixed); cout.precision(5); cout << "Time: " << double(tStop - tStart) / CLOCKS_PER_SEC << " s." << endl; return 0; }
Leave a Comment