Tuan trang mat

 avatar
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