hdu 2686(状压dp)
题目链接:http://poj.org/problem?id=2686
思路:典型的状压dp题,dp[s][v]表示到达剩下的车票集合为S并且现在在城市v的状态所需要的最小的花费。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 #define inf 1<<30 7 8 int n,m,p,a,b; 9 int t[11]; 10 int map[44][44]; 11 double dp[1<<11][44];//到达剩下的车票集合为S,并且现在在城市v的状态所需要的最小的花费 12 13 int main() 14 { 15 int u,v,w; 16 while(~scanf("%d%d%d%d%d",&n,&m,&p,&a,&b)){ 17 if(n==0&&m==0&&p==0&&a==0&&b==0)break; 18 for(int i=0;i<m;i++) 19 for(int j=0;j<m;j++) 20 map[i][j]=(i==j)?0:inf; 21 for(int i=0;i<n;i++)scanf("%d",&t[i]); 22 while(p--){ 23 scanf("%d%d%d",&u,&v,&w); 24 map[u-1][v-1]=w; 25 map[v-1][u-1]=w; 26 } 27 for(int state=0;state<(1<<n);state++){ 28 fill(dp[state],dp[state]+m,inf); 29 } 30 dp[(1<<n)-1][a-1]=0; 31 double ans=inf; 32 for(int state=(1<<n)-1;state>=0;state--){ 33 ans=min(ans,dp[state][b-1]); 34 for(int u=0;u<m;u++){ 35 for(int i=0;i<n;i++){ 36 if((state>>i)&1){ 37 for(int v=0;v<m;v++){ 38 if(map[u][v]<inf&&dp[state][u]<inf){ 39 dp[state&~(1<<i)][v]=min(dp[state&~(1<<i)][v],dp[state][u]+(double)map[u][v]/t[i]); 40 } 41 } 42 } 43 } 44 } 45 } 46 if(ans==inf){ 47 puts("Impossible"); 48 }else 49 printf("%.3f\n",ans); 50 } 51 return 0; 52 } 53 54 55 56 57