题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4284

思路:类似于poj3311:http://poj.org/problem?id=3311,首先floyd预处理出两点之间的最短距离,然后就是枚举所有的状态了。

hdu 4284(状压dp)_i++hdu 4284(状压dp)_我的dp之路_02
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 #define MAXN 111
 7 #define inf 0x3f3f3f3f
 8 
 9 int map[MAXN][MAXN];
10 int dp[1<<17][17];
11 int city[17],cost[17],value[17];
12 int N,M,H,money;
13 
14 void floyd()
15 {
16     for(int k=1;k<=N;k++)
17         for(int i=1;i<=N;i++)
18             for(int j=1;j<=N;j++)
19                 if(map[i][k]<inf&&map[k][j]<inf&&map[i][k]+map[k][j]<map[i][j])
20                     map[i][j]=map[i][k]+map[k][j];
21 }
22 
23 
24 int main()
25 {
26     int _case,u,v,w;
27     scanf("%d",&_case);
28     while(_case--){
29         scanf("%d%d%d",&N,&M,&money);
30         for(int i=1;i<=N;i++)
31             for(int j=1;j<=N;j++)
32                 map[i][j]=(i==j)?0:inf;
33         while(M--){
34             scanf("%d%d%d",&u,&v,&w);
35             map[u][v]=map[v][u]=min(map[u][v],w);
36         }
37         floyd();
38         scanf("%d",&H);
39         for(int i=0;i<H;i++){
40             scanf("%d%d%d",&city[i],&value[i],&cost[i]);
41         }
42         memset(dp,-1,sizeof(dp));
43         for(int i=0;i<H;i++){
44             int tmp=money-map[1][city[i]]-cost[i];
45             if(tmp>=0)dp[(1<<i)][i]=tmp+value[i];
46         }
47         for(int state=0;state<(1<<H);state++){
48             for(int i=0;i<H;i++){
49                 if((state&(1<<i))==0)continue;
50                 if(dp[state][i]<0)continue;
51                 for(int j=0;j<H;j++){
52                     if(state&(1<<j))continue;
53                     if(map[city[i]][city[j]]==inf)continue;
54                     if(dp[state][i]-map[city[i]][city[j]]-cost[j]<0)continue;
55                     dp[state|(1<<j)][j]=max(dp[state|(1<<j)][j],dp[state][i]-map[city[i]][city[j]]-cost[j]+value[j]);
56                 }
57             }
58         }
59         bool flag=false;
60         for(int i=0;i<H;i++){
61             if(dp[(1<<H)-1][i]-map[city[i]][1]>=0){
62                 flag=true;
63                 break;
64             }
65         }
66         flag?puts("YES"):puts("NO");
67     }
68     return 0;
69 }
70 
71             
72 
73         
74         
75 
76 
77 
78         
View Code