http://acm.hdu.edu.cn/showproblem.php?pid=3339
这道题就是dijkstra+01背包,先求一遍最短路,再用01背包求。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define maxn 100000 5 using namespace std; 6 const int inf=1<<30; 7 8 int n,m,st,ed,c; 9 int dis[maxn]; 10 bool vis[maxn]; 11 int g[500][500]; 12 int val[maxn]; 13 int dp[maxn]; 14 15 void dijkstra() 16 { 17 memset(vis,false,sizeof(vis)); 18 for(int i=0; i<=n; i++) dis[i]=(i==0?0:inf); 19 for(int i=0; i<=n; i++) 20 { 21 int m=inf,x; 22 for(int y=0; y<=n; y++) if(!vis[y]&&dis[y]<m) m=dis[x=y]; 23 vis[x]=true; 24 for(int y=0; y<=n; y++) dis[y]=min(dis[y],dis[x]+g[x][y]); 25 } 26 } 27 28 int main() 29 { 30 int t; 31 scanf("%d",&t); 32 while(t--) 33 { 34 scanf("%d%d",&n,&m); 35 memset(val,0,sizeof(val)); 36 for(int i=0; i<=n; i++) 37 { 38 for(int j=0; j<=n; j++) 39 { 40 if(i==j) g[i][j]=0; 41 else g[i][j]=inf; 42 } 43 } 44 for(int i=0; i<m; i++) 45 { 46 scanf("%d%d%d",&st,&ed,&c); 47 g[st][ed]=g[ed][st]=min(g[st][ed],c); 48 } 49 int ans=0; 50 for(int i=1; i<=n; i++) 51 { 52 scanf("%d",&val[i]); 53 ans+=val[i]; 54 } 55 dijkstra(); 56 int mm=ans; 57 for(int i=0; i<=mm; i++) 58 { 59 dp[i]=inf; 60 } 61 dp[0]=0; 62 for(int i=1; i<=n; i++) 63 { 64 if(dis[i]!=inf) 65 { 66 for(int v=mm; v>=val[i]; v--) 67 { 68 dp[v]=min(dp[v],dp[v-val[i]]+dis[i]); 69 } 70 } 71 } 72 mm=mm/2+1; 73 int m1=inf; 74 for(int i=mm; i<=ans; i++) 75 { 76 m1=min(m1,dp[i]); 77 } 78 if(m1>=inf) printf("impossible "); 79 else printf("%d ",m1); 80 } 81 return 0; 82 }