hdu 3339(01揹包+最短路)

題目連接:http://acm.hdu.edu.cn/showproblem.php?pid=3339php

大體題意是說:有n個電站,每一個電站都有必定的電量,電站之間有必定距離,咱們要從0點出發去佔領一些電站,使得佔領的電站電量之和超過總電量的一半,求達到條件所要走的最短距離。若是可能的話,輸出距離,不然輸出不可能。ios

思路:咱們從0點開始派出一些tank去佔領一些電站,坦克到每一個電站都有必定距離,而佔領每一個電站以後能夠獲得必定電量,距離就至關於體積v,電量就至關於價值w,這不是就01揹包嗎?01揹包一般的問法是給定體積,求得到最大的價值,這裏的問法是給訂價值,求剛好獲得或多於該價值時的最小體積。咱們只要從前向後搜索,找到第一個大於該價值的體積便可。ide

不過一開始我就被坑了,我令inf=0x7fffffff,而後就wa了好屢次,最後該成小一些的數,就過了,orz;spa

View Code
 1 #include<iostream>
 2 #include<cstring>
 3 const int N=111;
 4 const int inf=0x7fffff;
 5 using namespace std;
 6 int n,m;
 7 int edge[N][N];
 8 int visited[N];
 9 int dist[N];
10 int dp[N*N],power[N];
11 
12 void Dijkstra(int v0){
13     memset(visited,0,sizeof(visited));
14     for(int i=1;i<=n;i++){
15         dist[i]=edge[v0][i];
16     }
17     visited[v0]=1;
18     for(int i=1;i<n;i++){
19         int min=inf,u=v0;
20         for(int j=1;j<=n;j++){
21             if(!visited[j]&&dist[j]<min){
22                 min=dist[j],u=j;
23             }
24         }
25         if(min==inf)return ;
26         visited[u]=1;
27         for(int k=1;k<=n;k++){
28             if(!visited[k]&&dist[u]+edge[u][k]<dist[k]){
29                 dist[k]=dist[u]+edge[u][k];
30             }
31         }
32     }
33 }
34 
35 int main(){
36     int _case;
37     scanf("%d",&_case);
38     while(_case--){
39         scanf("%d%d",&n,&m);
40         for(int i=0;i<=n;i++){
41             for(int j=0;j<=n;j++){
42                 if(i==j){
43                     edge[i][j]=0;
44                 }else 
45                     edge[i][j]=inf;
46             }
47         }
48         int x,y,d;
49         for(int i=1;i<=m;i++){
50             scanf("%d%d%d",&x,&y,&d);
51             if(d<edge[x][y]){
52                 edge[x][y]=edge[y][x]=d;
53             }
54         }
55         for(int i=1;i<=n;i++){
56             scanf("%d",&power[i]);
57         }
58         Dijkstra(0);
59         bool flag=true;
60         int v=0,w=0;
61         for(int i=1;i<=n;i++){
62             w+=power[i];
63             v+=dist[i];
64             if(dist[i]==inf){
65                 flag=false;
66                 break;
67             }
68         }
69         if(!flag){
70             printf("impossible\n");
71             continue;
72         }
73         for(int i=0;i<=v;i++){
74             dp[i]=0;
75         }
76         for(int i=1;i<=n;i++){
77             for(int j=v;j-dist[i]>=0;j--){
78                 dp[j]=(dp[j-dist[i]]+power[i])>dp[j]?(dp[j-dist[i]]+power[i]):dp[j];
79             }
80         }
81         w=w/2+1;
82         for(int i=1;i<=v;i++){
83             if(dp[i]>=w){
84                 printf("%d\n",i);
85                 break;
86             }
87         }
88     }
89     return 0;
90 }
相關文章
相關標籤/搜索