Travelling
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission (s): 2520 Accepted Submission (s): 735
Problem Description
After coding so many days, Mr Acmer wants to have a good rest. So traveling is the best choice! He has decided to visit n cities (he insists on seeing all the cities! And he does not mind which city being his start station because superman can bring him to any city at first but only once .), and of course there are m roads here, following a stored as usual. but Mr Acmer gets bored so easily that he doesn't want to visit a city more than twice! And he is so mean that he wants to minimize the total amount! He is lazy you see. So he turns to you for help.
Input
There are several test cases, the first line is two intergers n (1 <= n <= 10) and m, which means he needs to visit n cities and there are m roads he can choose, then m lines follow, each line will include three intergers a, B and c (1 <=, B <= n), means there is a road between a and B and the cost is of course c. input to the End Of File.
Output
Output the minimum blocks that he shoshould pay, or-1 if he can't find such a route.
Sample Input
2 1
1 2 100
3 2
1 2 40
2 3 50
3 3
1 2 3
1 3 4
2 3 10
Sample Output
100
90
7
Use the three-in-one mechanism to perform forced compression, which can greatly reduce the number of states. After preprocessing, you can proceed. Secondly, every point must be taken once!
# Include <iostream> # include <stdio. h> using namespace std; int threenum [11] = {81,243,729,218, 600000, 19683,59049}; # define inf 0x4f4f4f4f int dp [] [15], n, m; int threeevery [1, 600000] [15], dis [15] [15]; int fmin (int x, int y) {if (x <y) return x; return y ;} void makethree () // preprocessing first, calculate all values {int I, temp, j; for (I = 0; I <threenum [10]; I ++) // 11 times of 3 {temp = I; for (j = 0; j <10; j ++) {threeevery [I] [j] = temp % 3; temp = te Mp/3 ;}} void init () {int I, j, s, e, val; for (I = 0; I <threenum [n]; I ++) {for (j = 0; j <n; j ++) {dp [I] [j] = inf ;}} for (I = 0; I <n; I ++) for (j = 0; j <n; j ++) {dis [I] [j] = inf;} for (I = 0; I <n; I ++) {dp [threenum [I] [I] = 0; // initialize to 0} for (I = 0; I <m; I ++) {scanf ("% d", & s, & e, & val); s --; e --; // open all from 0 # include <iostream> # include <stdio. h> using namespace std; int threenum [11] = {81,243,729,218,}; # d Efine inf 0x4f4f4f4fint dp [600000] [15], n, m; int threeevery [600000] [15], dis [15] [15]; int fmin (int x, int y) {if (x <y) return x; return y;} void makethree () // preprocessing first, calculate all the values {int I, temp, j; for (I = 0; I <threenum [10]; I ++) // 11 times of 3 {temp = I; for (j = 0; j <10; j ++) {threeevery [I] [j] = temp % 3; temp = temp/3 ;}} void init () {int I, j, s, e, val; for (I = 0; I <threenum [n]; I ++) {for (j = 0; j <n; j ++) {dp [I] [j] = inf ;}for (I = 0; I <n; I ++) for (j = 0; j <n; j ++) {dis [I] [j] = inf ;}for (I = 0; I <n; I ++) {dp [threenum [I] [I] = 0; // initialize to 0} for (I = 0; I <m; I ++) {scanf ("% d", & s, & e, & val); s --; e --; // all open [html] view plaincopyprint from 0? If (val <dis [s] [e]) dis [s] [e] = dis [e] [s] = val; // exclude the minimum value of the duplicate edge} int makedp () {int I, j, k, minx; bool flag; minx = inf; for (I = 0; I <threenum [n]; I ++) // calculate {flag = true for each bit; // mark whether each vertex has passed for (j = 0; j <n; j ++) {if (threeevery [I] [j] = 0) // This vertex is not flag = false; if (dp [I] [j] = inf) // {continue;} for (k = 0; k <n; k ++) // Add the k point {if (j = k) | threeevery [I] [k]> = 2 | (dis [j] [k] = inf) // after arriving at your own location for more than two times, remove continue from disconnections; dp [I + threenu M [k] [k] = fmin (dp [I + threenum [k] [k], dp [I] [j] + dis [j] [k]); // from j to k} if (flag) // meets the conditions, update the minimum value {for (j = 0; j <n; j ++) {minx = fmin (dp [I] [j], minx );}}} if (minx = inf) {minx =-1;} printf ("% d \ n", minx); return 1 ;}int main () {makethree (); while (scanf ("% d", & n, & m )! = EOF) {init (); makedp () ;}return 0 ;}if (val <dis [s] [e]) dis [s] [e] = dis [e] [s] = val; // exclude the minimum value of the duplicate edge} int makedp () {int I, j, k, minx; bool flag; minx = inf; for (I = 0; I <threenum [n]; I ++) // calculate {flag = true for each bit; // mark whether each vertex has passed through for (j = 0; j <n; j ++) {if (threeevery [I] [j] = 0) // flag = false is not used at this point; if (dp [I] [j] = inf) // It has not passed through {continue;} for (k = 0; k <n; k ++) // Add the k point {if (j = k) | threeevery [I] [k]> = 2 | (dis [j] [k] = inf) // go to your own location, After more than two times, the continue is not connected. dp [I + threenum [k] [k] = fmin (dp [I + threenum [k] [k], dp [I] [j] + dis [j] [k]); // from j to k} if (flag) // meets the conditions, update the minimum value {for (j = 0; j <n; j ++) {minx = fmin (dp [I] [j], minx );}}} if (minx = inf) {minx =-1;} printf ("% d \ n", minx); return 1 ;}int main () {makethree (); while (scanf ("% d", & n, & m )! = EOF) {init (); makedp () ;}return 0 ;}