HDU3339 最短路加01背包

来源:互联网 发布:淘宝店铺音乐怎么换 编辑:程序博客网 时间:2024/05/21 00:54


题意大意就是说:有n个电站,每个电站都有一定的电量,电站之间有一定的距离,我们要从0点出发去占据一些电站,使得占据的电站电量之和不小于总电量的一半,求达到要求所要走的最短距离。若是可能的话,输出间隔,不然输出不成能。我们知道电站都是连通的,只要0点与任何一个电站连通,我们就可以占据所有电站,若是0点不与任何一个电站相连,就是不成能实现,也就是说0点到任何一个电站的间隔都是无穷。

 

我们从0点开端派出一些坦克去占据一些电站,坦克到每个电站都有必然间隔,而占据每个电站之后可以获得必然电量,间隔就相当于体积,电量就相当于价值,这不是就01背包吗?01背包凡是的问法是给定体积,求获得最大的价值,这里的问法是给订价值,求正好获得或多于该价值时的最小体积。我们只要畴前向后搜刮,找到第一个大于该价值的体积即可。

#include <stdio.h>#include <iostream>#include <algorithm>#include <string.h>#include <math.h>#define INF 999999999#define M 105using namespace std;int main(){    int map[M][M],p[M],dp[M*M];    int n,m,t,i,j,k,sum,ave;    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&m);        for(i=0;i<=n;i++)        {            for(j=0;j<=n;j++)            {                map[i][j]=INF;            }        }        while(m--)        {            int u,v,d;            scanf("%d%d%d",&u,&v,&d);            map[u][v]=map[v][u]=min(map[u][v],d);        }        sum=0;        for(i=1;i<=n;i++)        {            scanf("%d",&p[i]);            sum+=p[i];        }        ave=sum/2;        for(k=0;k<=n;k++)        {            for(i=0;i<=n;i++)            {                for(j=0;j<=n;j++)                {                    map[i][j]=min(map[i][j],map[i][k]+map[k][j]);                }            }        }        int temp=0;        for(i=1;i<=n;i++)        {            if(map[0][i]<INF-10)                temp+=map[0][i];        }        memset(dp,0,sizeof(dp));        for(i=1;i<=n;i++)        {            for(j=temp;j>=map[0][i];j--)            {                dp[j]=max(dp[j],dp[j-map[0][i]]+p[i]);            }        }        int flag=0;        for(i=0;i<=temp;i++)        {            if(dp[i]>ave)            {                printf("%d\n",i);                flag=1;                break;            }        }        if(flag==0)            printf("impossible\n");    }    return 0;}


0 0
原创粉丝点击