hdu 4284(状压dp)

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

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

 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

 

你可能感兴趣的:(HDU)