自1945年以来,当美国的曼哈顿项目小组引爆了第一颗核弹时,全球的核武器数量急剧增加。
如今,FZU的一个名叫AekdyCoin的疯狂男孩拥有核武器,想要毁灭我们的世界。幸运的是,我们神秘的间谍网络已经得到了他的计划。现在,我们需要阻止它。
但这项艰巨的任务显然并不容易。首先,我们知道,核武器的操作系统由一些连接的电站组成,它们构成了一个庞大而复杂的电网。每个电站都有它的功率值。要启动核武器,它必须消耗电网一半的电力。所以首先,我们需要将一半以上的能量分散。我们的坦克已经为我们在基地的行动做好了准备(ID是0),我们必须在路上驾驶它们。至于发电站,只有当我们的坦克停在那里时,我们才能控制它们。1单位距离花费1单位油。我们有足够的坦克使用。
现在我们的指挥官想知道这次行动的最小石油成本。
Input
输入数据的第一行包含一个整数T,表示文件中测试点的数量。
对于每组数据,第一行有两个整数n(1<= n<= 100), m(1<= m<= 10000),指定站点的数量(id为1、2、3…n),以及站点之间的道路数量(双向)。
接下来的m行,每一行都有三个整数 st(0<= st<= n), ed(0<= ed<= n), dis(0<= dis<= 100),指定起始点、结束点和它们之间的距离。
接下来的n行,每一行都有一个整数pow(1<= pow<= 100),按ID顺序表示各电站的功率。
Output
输出最低的石油成本。
若不存在则输出 “impossible”(不带引号).
Sample Input
2
2 3
0 2 9
2 1 3
1 0 2
1
3
2 1
2 1 3
1
3
Sample Output
5
impossible
注意:是要选择1~n的点放坦克,而不是路过而已;
然后这里求最短路用的是Floyd,求出0到1~n各个点的最短路,然后01背包选点;
#include <iostream>
#include <stdio.h>
#include <string>
#include<cstring>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <set>
#include <map>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 200;
int mz[maxn][maxn],path[maxn][maxn],val[maxn];
int n,m;
void floyd()
{
for(int k=0;k<=n;k++)
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
if(mz[i][j]>mz[i][k]+mz[k][j]){
mz[i][j]=mz[i][k]+mz[k][j];
path[i][j]=k;
}
}
//忽略get_path函数以及path数组
void get_path(int u,int v,vector<pair<int,int>>&p)
{
if(path[u][v]==-1)p.push_back({u,v});
else{
int mid=path[u][v];
get_path(u,mid,p);
get_path(mid,v,p);
}
}
int main()
{
int t;
scanf("%d",&t);
while (t--){
memset(mz,INF,sizeof(mz));
memset(path,-1,sizeof(path));
memset(val,0,sizeof(val));
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if(a==b)continue;
if(mz[a][b]!=INF){
int s=mz[a][b];
mz[a][b]=min(c,s);
mz[b][a]=mz[a][b];
} else{
mz[a][b]=c;
mz[b][a]=mz[a][b];
}
}
int sum=0;
for(int i=1;i<=n;i++) {
scanf("%d", &val[i]);
sum+=val[i];
}
sum/=2;
floyd();
int temp=0;
for(int i=1;i<=n;i++)
if(mz[0][i]!=INF)
temp+=mz[0][i];
int dp[10005];
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
for(int j=temp;j>=mz[0][i];j--)
{
dp[j]=max(dp[j],dp[j-mz[0][i]]+val[i]);
}
bool flag=0;
for(int i=0;i<=temp;i++)
if(dp[i]>sum){
printf("%d\n",i);
flag=1;
break;
}
if(!flag)
printf("impossible\n");
}
return 0;
}