HDU 3339 In Action
最短路径+01背包。。
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<queue> using namespace std; const int INF=1<<30; int edge[105][105], dis[105], po[105], dp[1000005], n; bool vis[105]; void dijkstra() { int i, j, k, minv; memset(vis,0,sizeof(vis)); for(i=0;i<=n;i++) { minv=INF; for(j=0;j<=n;j++) { if(dis[j]<minv&&!vis[j]) { k=j; minv=dis[j]; } } if(minv==INF) break; vis[k]=true; for(j=1;j<=n;j++) { if(!vis[j]) dis[j]=min(dis[j],dis[k]+edge[k][j]); } } } int main() { int m, i, j, a, b, c, sum, T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(i=0;i<=n;i++) for(j=0;j<=n;j++) edge[i][j]=INF; for(i=0;i<m;i++) { scanf("%d%d%d",&a,&b,&c); edge[a][b]=edge[b][a]=min(edge[a][b],c); } for(i=1;i<=n;i++) dis[i]=INF; dis[0]=0; dijkstra(); sum=0; for(i=1;i<=n;i++) scanf("%d",&po[i]), sum+=po[i]; int vv=0; for(i=1;i<=n;i++) { if(dis[i]!=INF) vv+=dis[i]; } memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++) { if(dis[i]==INF) continue; for(j=vv;j>=dis[i];j--) { dp[j]=max(dp[j],dp[j-dis[i]]+po[i]); } } int ans; bool f=false; for(i=0;i<=vv;i++) { if(dp[i]>sum/2) { ans=i; f=true; break; } } if(f) printf("%d\n",ans); else printf("impossible\n"); } return 0; }