感觉这题出的不错,最短路+dp(01背包);

好长时间没做过dp题了,做的时候又翻开算法开了一下,背包基本上忘完了,这段时间要好好的复习的一下。。

题目大意就是总共有n个核电站,然后每个核电站都有一个能量power, 需要把总能量的一半以上消耗掉!

从一个地方开坦克到这些核电站,坦克到达一个核电站,这个核电站的所有能量都被消耗了,这个坦克也必须留在这个核电站里!

每个坦克1 unit distance costs 1 unit oil;问最少需要消耗多少oil  !!

最短路直接就用floyd,接下来就是01背包,思路很清晰!

代码:

# include<stdio.h>
# include
<string.h>
# define PI
2000000
int n,adj[105][105],f[105][5005];
int min(int a,int b)
{
if(a<b) return a;
return b;
}
void floyd()
{
int i,j,k;
for(k=0;k<=n;k++)
{
for(i=0;i<=n;i++)
{
if(i==k || adj[i][k]==-1) continue;
for(j=0;j<=n;j++)
{
if(j==k || j==i || adj[k][j]==-1) continue;
if(adj[i][j]==-1 || adj[i][k]+adj[k][j] < adj[i][j]) adj[i][j]=adj[i][k]+adj[k][j];
}
}
}
}
int main()
{
int i,j,m,t,s[105],a,b,c,ans;
scanf(
"%d",&t);
while(t--)
{
memset(adj,
-1,sizeof(adj));
scanf(
"%d%d",&n,&m);
for(i=1;i<=m;i++)
{
scanf(
"%d%d%d",&a,&b,&c);
if(adj[a][b]==-1 || adj[a][b]>c) {adj[a][b]=c; adj[b][a]=c;}
}
floyd();
//求最短路
ans=0;
for(i=1;i<=n;i++)
{
scanf(
"%d",&s[i]);
ans
+=s[i];
}
ans
=ans/2+1;
for(j=0;j<=ans;j++)
f[
0][j]=PI;
for(i=1;i<=n;i++)
{
if(adj[i][0]==-1)
{
for(j=1;j<=ans;j++)
f[i][j]
=f[i-1][j];
}
else
{
for(j=1;j<=ans;j++)
{
if(s[i]>=j) f[i][j]=min(adj[i][0],f[i-1][j]);
else f[i][j]=min(adj[i][0]+f[i-1][j-s[i]],f[i-1][j]);
}
}
}
if(f[n][ans]==PI) printf("impossible\n");
else printf("%d\n",f[n][ans]);
}
return 0;
}
posted on 2011-03-17 09:14  奋斗青春  阅读(618)  评论(0编辑  收藏  举报