poj3311_状压dp+Dijkstra
题目链接:http://poj.org/problem?id=3311
题意:快递员从披萨店(0)出发,送往n家,可重复走,最后回到披萨店,问用时最少是多少?
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <cstdlib> 6 #include <cmath> 7 #include <set> 8 #include <map> 9 #include <queue> 10 #include <vector> 11 #define INF 0x3f3f3f3f 12 using namespace std; 13 14 const int N = 11, M = 1 << N; 15 int dp[M][N], a[12][12], n, used[12], dist[12][12]; 16 void djs() 17 { 18 for(int i = 0; i < n; i++) 19 for(int j = 0; j < n; j++) 20 dist[i][j] = INF; 21 for(int i = 0; i < n; i++) 22 { 23 memset(used, 0, sizeof(used)); 24 used[i] = 1; 25 for(int j = 0; j < n; j++) 26 dist[i][j] = a[i][j]; 27 while(1) 28 { 29 int u = -1, MIN = INF; 30 for(int j = 0; j < n; j++) 31 { 32 if(!used[j] && dist[i][j] < MIN) 33 { 34 u = j; 35 MIN = dist[i][j]; 36 } 37 } 38 if(u == -1) 39 break; 40 used[u] = 1; 41 for(int j = 0; j < n; j++) 42 dist[i][j] = min(dist[i][j], dist[i][u] + a[u][j]); 43 } 44 } 45 } 46 int main() 47 { 48 while(~scanf("%d", &n) && n) 49 { 50 n++; 51 for(int i = 0; i < n; i++) 52 for(int j = 0; j < n; j++) 53 scanf("%d", &a[i][j]); 54 djs(); 55 for(int i = 0; i < (1 << n); i++) 56 for(int j = 0; j < n; j++) 57 dp[i][j] = INF; 58 dp[1][0] = 0; 59 for(int i = 1; i < (1 << n); i++) 60 { 61 for(int j = 0; j < n; j++) 62 { 63 if(i & (1 << j)) 64 { 65 for(int k = 0; k < n; k++) 66 { 67 int next = i | (1 << k); 68 dp[next][k] = min(dp[i][j] + dist[j][k], dp[next][k]); 69 } 70 } 71 } 72 } 73 int x = (1 << n) - 1, res = INF; 74 for(int i = 1; i < n; i++) 75 { 76 res = min(dp[x][i] + dist[i][0], res); 77 } 78 printf("%d\n", res); 79 } 80 return 0; 81 }