
2 2 3 0 2 9 2 1 3 1 0 2 1 3 2 1 2 1 3 1 3
5 impossible
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define INF 9999999
int dis[101],map[101][101],pow[101],T,n,m,sumpow,sumdis,f[10000];
bool vis[101];
int main()
{
int i,j;
scanf("%d",&T);
while(T--)
{
memset(map,INF,sizeof(map));
memset(dis,INF,sizeof(dis));
memset(vis,0,sizeof(vis));
memset(f,0,sizeof(f));
scanf("%d%d",&n,&m);
for(i=0;i<m;i++)
{
int t1,t2,t3;
scanf("%d%d%d",&t1,&t2,&t3);
if(map[t1][t2]>t3) map[t1][t2]=map[t2][t1]=t3;
if(t1==0) dis[t2]=min(dis[t2],t3);
if(t2==0) dis[t1]=min(dis[t1],t3);
}
sumpow=0;
for(i=1;i<=n;i++)
{
scanf("%d",&pow[i]);
sumpow+=pow[i];
}
//Dijkstra求最短路
int t1=n-1;
while(t1--)
{
int minindex=0;
for(i=1;i<=n;i++)
if(!vis[i] && dis[i]<dis[minindex]) minindex=i;
vis[minindex]=1;
for(i=1;i<=n;i++)
if(map[minindex][i]+dis[minindex]<dis[i]) dis[i]=map[minindex][i]+dis[minindex];
}
//----------------------------------
sumdis=0;
for(i=1;i<=n;i++) if(dis[i]<INF) sumdis+=dis[i];
//01背包
for(i=1;i<=n;i++)
for(j=sumdis;j>=dis[i];j--)
f[j]=max(f[j],f[j-dis[i]]+pow[i]);
//f[j]表示走j距离可以破坏的最大电力和
int flag=0;
for(i=1;i<=sumdis;i++)
{
if(f[i]>=sumpow/2+1)
{
printf("%d\n",i);
flag=1;
break;
}
}
if(!flag) printf("impossible\n");
}
}
HDU-3339-In Action(Dijkstra+01背包),布布扣,bubuko.com
HDU-3339-In Action(Dijkstra+01背包)
原文:http://blog.csdn.net/faithdmc/article/details/20999691