dij+01背包
#include<iostream> using namespace std; # define inf 1000000000 int adj[101][101]; struct sta { int dis,pow; }st[110]; int max(int a,int b) { return a>b?a:b; } void Dijkstra(int n,int s) { int i,j; bool b[101]; for(i=0;i<=n;i++) { b[i]=0; st[i].dis=adj[s][i]; } b[s]=1; for(i=0;i<n;i++) { int tmp=inf,u=s; for(j=0;j<=n;j++) if(b[j]==0 && st[j].dis<tmp) {tmp=st[j].dis;u=j;} b[u]=1; for(j=0;j<=n;j++) if(b[j]==0 && adj[u][j]<inf) { int tt=st[u].dis+adj[u][j]; if(st[j].dis>tt) st[j].dis=tt; } } } int main() { int i,j,t; cin>>t; while(t--) { int n,m; scanf("%d%d",&n,&m); for(i=0;i<=n;i++) for(j=0;j<=n;j++) { if(i!=j) adj[i][j]=inf; else adj[i][j]=0; } for(i=0;i<m;i++) { int s,t,dd; scanf("%d%d",&s,&t); scanf("%d",&dd); if(dd<adj[s][t]) adj[t][s]=adj[s][t]=dd; //注意! } for(i=1;i<=n;i++) scanf("%d",&st[i].pow); Dijkstra(n,0); int bag=0,f=1,total=0; for(i=1;i<=n && f;i++) { bag+=st[i].dis; total+=st[i].pow; if(st[i].dis==inf) f=0; } if(!f) printf("impossible\n"); else { int opt[100001]; for(i=0;i<=bag;i++) opt[i]=0; for(i=1;i<=n;i++) //背包 for(j=bag;j>=st[i].dis;j--) opt[j]=max(opt[j],opt[j-st[i].dis]+st[i].pow); total=total/2+1; for(i=1;i<=bag;i++) if(opt[i]>=total) {printf("%d\n",i);break;} } } return 0; }