hdu 4114(状压dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4114
思路:首先是floyd预处理出任意两点之间的最短距离。dp[state1][state2][u]表示在该状态state1(已经访问过的景点)、state2(手中有的景点的票)、目前所在的位置时所花费的时间的最小值,于是答案就是dp[(1<<k)-1][state][1]了(0<=state<(1<<n))。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 #include<vector> 7 using namespace std; 8 #define inf 1<<30 9 #define FILL(a,b) memset(a,b,sizeof(a)) 10 11 int dp[1<<9][1<<9][55];//访问过的+收集的票+当前顶点 12 int pos[55],time[9],f_time[9],map[55][55]; 13 int Mask[55]; 14 int n,m,k,ans; 15 16 void floyd() 17 { 18 for(int k=1; k<=n; k++) 19 for(int i=1; i<=n; i++) 20 for(int j=1; j<=n; j++) 21 if(map[i][k]!=inf&&map[k][j]!=inf&&map[i][k]+map[k][j]<map[i][j]) 22 map[i][j]=map[i][k]+map[k][j]; 23 } 24 25 void Get_Dp() 26 { 27 for(int i=0; i<=(1<<k); i++) 28 for(int j=0; j<=(1<<k); j++) 29 for(int u=1; u<=n; u++)dp[i][j][u]=inf; 30 dp[0][0][1]=0; 31 for(int state1=0; state1<(1<<k); state1++) { 32 for(int state2=0; state2<(1<<k); state2++) { 33 for(int u=1; u<=n; u++)if(dp[state1][state2][u]<inf) { 34 for(int i=0; i<k; i++)if(!(state1&(1<<i))) { 35 int cost=map[u][pos[i]]; 36 if(state2&(1<<i))cost+=f_time[i]; 37 else cost+=time[i]; 38 dp[state1|(1<<i)][state2|Mask[pos[i]]][pos[i]]=min(dp[state1|(1<<i)][state2|Mask[pos[i]]][pos[i]],dp[state1][state2][u]+cost); 39 } 40 for(int v=1; v<=n; v++) { 41 dp[state1][state2|Mask[v]][v]=min(dp[state1][state2|Mask[v]][v],dp[state1][state2][u]+map[u][v]); 42 } 43 } 44 } 45 } 46 ans=inf; 47 for(int state=0;state<(1<<k);state++){ 48 ans=min(ans,dp[(1<<k)-1][state][1]); 49 } 50 } 51 52 53 int main() 54 { 55 int _case,u,v,w,num,t=1; 56 scanf("%d",&_case); 57 while(_case--) { 58 scanf("%d%d%d",&n,&m,&k); 59 for(int i=1; i<=n; i++) 60 for(int j=1; j<=n; j++)map[i][j]=(i==j?0:inf); 61 while(m--) { 62 scanf("%d%d%d",&u,&v,&w); 63 map[u][v]=map[v][u]=min(map[u][v],w); 64 } 65 FILL(Mask,0); 66 for(int i=0; i<k; i++) { 67 scanf("%d%d%d%d",&pos[i],&time[i],&f_time[i],&num); 68 while(num--) { 69 scanf("%d",&v); 70 Mask[v]|=(1<<i); 71 } 72 } 73 floyd(); 74 Get_Dp(); 75 printf("Case #%d: %d\n",t++,ans); 76 } 77 return 0; 78 }