POJ 3311 Hie with the Pie(DP状态压缩+最短路径)

题目链接:http://poj.org/problem?id=3311

题目大意:一个送披萨的,每次送外卖不超过10个地方,给你这些地方之间的时间,求送完外卖回到店里的总时间最小。

Sample Input

3
0 1 10 10
1 0 1 2
10 1 0 10
10 2 10 0
0

Sample Output

8

分析:dp[i][j]:表示在i状态(用二进制表示城市有没有经过)时最后到达j城市的最小时间,转移方程:dp[i][j]=min(dp[i][k]+d[k][j],dp[i][j])  d[k][j]是k城市到j城市的最短距离,显然要先用flody处理一下。

代码如下:
 1 # include<stdio.h>
 2 # include<string.h>
 3 int map[11][11],n,m,dp[1<<11][11];
 4 const int INF = 1<<30;
 5 
 6 int min(int a,int b){
 7     return a<b ?a :b;
 8 }
 9 
10 void flody(){
11     int i,j,k;
12     for(k=0; k<=n; k++)
13         for(i=0; i<n; i++)
14             for(j=0; j<=n; j++){
15                 if(map[i][k] + map[k][j] < map[i][j])
16                     map[i][j] = map[i][k] + map[k][j];
17             }
18 }
19 int main(){
20     int i,j,k;
21     while(scanf("%d",&n) && n){
22         for(i=0; i<=n; i++)
23             for(j=0; j<=n; j++)
24                 scanf("%d",&map[i][j]);
25             flody();
26             int ans = INF;
27             for(i=0; i<(1<<n); i++)
28                 for(j=1; j<=n; j++)
29                     if(i==(1<<(j-1)))
30                         dp[i][j] = map[0][j];
31                     else
32                         if(i & (1<<(j-1))){
33                             dp[i][j] = INF;
34                             for(k=1; k<=n; k++)
35                                 if(k!=j && (i & (1<<(k-1))))
36                                     dp[i][j] = min(dp[i^(1<<(j-1))][k] + map[k][j],dp[i][j]);
37                         }
38                         for(i=1; i<=n; i++)
39                             ans = min(ans, dp[(1<<n)-1][i]+map[i][0]);
40                         printf("%d\n",ans);
41     }
42     return 0;
43 }

 

 

 

你可能感兴趣的:(with)