
2 2 3 0 2 9 2 1 3 1 0 2 1 3 2 1 2 1 3 1 3
5 impossible
问控制一半以上的核值,需要最 少的油费?
题解:一开始理解成只要有坦克经过就相当于销毁了一个核电站,硬是搞不出来。看懂题意后不就是最短路+01背包么。。
先跑最短路求出0到任意点的最短距离,然后背包求出大于一般核值得最小油费。
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cstdio>
using namespace std;
const int MAXN=110;
const int INF=0x3f3f3f3f;
bool vis[MAXN];
int lowcost[MAXN],cost[MAXN][MAXN];
int n,m;
void Dijkstra(int beg) {
for(int i=0; i<n; i++) {
lowcost[i]=INF;
vis[i]=false;
}
lowcost[beg]=0;
for(int j=0; j<n; j++) {
int k=-1;
int Min=INF;
for(int i=0; i<n; i++)
if(!vis[i]&&lowcost[i]<Min) {
Min=lowcost[i];
k=i;
}
if(k==-1)break;
vis[k]=true;
for(int i=0; i<n; i++)
if(!vis[i]&&lowcost[k]+cost[k][i]<lowcost[i]) {
lowcost[i]=lowcost[k]+cost[k][i];
}
}
}
int val[MAXN];
int dp[MAXN*MAXN];
int main() {
//freopen("test.in","r",stdin);
int t;
cin>>t;
while(t--) {
scanf("%d%d",&n,&m);
n++;
int u,v,w;
for(int i=0; i<n; i++)
for(int j=i; j<n; j++) {
if(i==j)cost[i][j]=0;
else cost[i][j]=cost[j][i]=INF;
}
for(int i=1; i<=m; i++) {
scanf("%d%d%d",&u,&v,&w);
cost[u][v]=cost[v][u]=min(cost[u][v],w);
}
int sum=0;
for(int i=1; i<n; i++) {
scanf("%d",&val[i]);
sum+=val[i];
}
Dijkstra(0);
for(int i=0; i<=sum; i++)dp[i]=INF;
dp[0]=0;
for(int i=1; i<n; i++) {
for(int j=sum; j>=val[i]; j--)
dp[j]=min(dp[j],dp[j-val[i]]+lowcost[i]);
}
int ans=INF;
for(int i=sum/2+1; i<=sum; i++) {
ans=min(ans,dp[i]);
}
if(ans==INF)printf("impossible\n");
else printf("%d\n",ans);
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/acm_baihuzi/article/details/47738301