NYOJ 203

View Code
  1 /*
  2 最短路  +  0-1背包 
  3 先用 DIJ 求出  起点到各个点的最短距离 相当于
  4 各个物品的体积,各个点的宝物数 相当于 价值
  5 总粮食相当于 背包容量
  6 剩下的就是  纯粹的 0-1背包问题了 
  7 */
  8 #include<iostream>
  9 #include<cstdio>
 10 #include<cstring>
 11 #include<algorithm>
 12 using namespace std;
 13 
 14 const int size = 110;
 15 const int inf = 999999999;
 16 
 17 int v[size];
 18 int f[1000005];
 19 int w[size];
 20 int path[size][size];
 21 bool flag[size];
 22 int c,n,M;
 23 
 24 void init()
 25 {
 26   int i,j;
 27   for(i=0;i<=n;++i)
 28    {
 29      flag[i]=false;
 30      path[i][i]=0;
 31      w[i]=inf;
 32      for(j=i+1;j<=n;++j)
 33       path[i][j]=path[j][i]=inf;
 34    }
 35 }
 36 
 37 void dij()
 38 {
 39    int i,j;
 40    w[0]=0;
 41    
 42    for(i=0;i<=n;++i)
 43     {
 44        int mi=inf;
 45        int k=0;
 46        for(j=0;j<=n;++j)
 47         if(!flag[j]&&w[j]<mi)
 48          {
 49            mi=w[j];
 50            k=j;
 51          }
 52        flag[k]=true;
 53        for(j=0;j<=n;++j)
 54         {
 55           if(!flag[j] && w[j]>mi+path[k][j]&& path[k][j]!=inf)
 56            {
 57               w[j]=mi+path[k][j];
 58            }
 59         }
 60     }
 61 }
 62 
 63 /*void Knapsack()
 64 {
 65    int jMax=min(w[n]-1,c);
 66    for(int j=0;j<=jMax;++j)
 67     m[n][j]=0;
 68    for(int j=w[n];j<=c;++j)
 69     m[n][j]=v[n];
 70    for(int i=n-1;i>1;--i)
 71     {
 72       jMax=min(w[i]-1,c);
 73       for(int j=0;j<=jMax;j++)
 74        m[i][j]=m[i+1][j];
 75       for(int j=w[i];j<=c;++j)
 76        m[i][j]=max(m[i+1][j],m[i+1][j-w[i]]+v[i]);
 77     }
 78    m[1][c]=m[2][c];
 79    if(c>=w[1])m[1][c]=max(m[1][c],m[2][c-w[1]]+v[1]);
 80    printf("%d\n",m[1][c]);
 81 }
 82 */
 83 
 84 void Knapsack()
 85 {
 86    int i,j;
 87    for(i=1;i<=n;++i)
 88     for(j=c;j>=w[i];--j)
 89      if(f[j]<f[j-w[i]]+v[i])
 90       f[j]=f[j-w[i]]+v[i];
 91 }
 92 int main()
 93 {
 94   int T,i,j,x,y,z,num,sum;
 95   
 96   scanf("%d",&T);
 97   while(T--)
 98    {     
 99      scanf("%d%d%d",&c,&n,&M);
100      init();
101      for(i=0;i<M;++i)
102       {
103         scanf("%d%d%d",&x,&y,&z);
104         if(path[x][y]>z)
105         path[x][y]=path[y][x]=z;
106       }
107      dij();
108      for(i=1;i<=n;++i)
109        scanf("%d",&v[i]);
110      for(i=0;i<=c;++i)
111        f[i]=0;
112      Knapsack();
113      printf("%d\n",f[c]);
114    }
115   return 0;
116 }

 

posted @ 2012-05-10 20:14  知行执行  阅读(147)  评论(0编辑  收藏  举报