zoukankan      html  css  js  c++  java
  • hdu 3339 In Action (最短路+01背包)

    大致题意是说:有n个电站,每个电站都有一定的电量,电站之间有一定距离,我们要从0点出发去占领一些电站,使得占领的电站电量之和超过总电量的一半,求达到条件所要走的最短距离。如果可能的话,输出距离,否则输出不可能。我们知道电站都是连通的,只要0点与任何一个电站连通,我们就可以占领所有电站,如果0点不与任何一个电站相连,就是不可能实现,也就是说0点到任何一个电站的距离都是无穷。    

     我们从0点开始派出一些坦克去占领一些电站,坦克到每个电站都有一定距离,而占领每个电站之后可以得到一定电量,距离就相当于体积,电量就相当于价值,这不是就01背包吗?01背包通常的问法是给定体积,求获得最大的价值,这里的问法是给定价值,求恰好得到或多于该价值时的最小体积。我们只要从前向后搜索,找到第一个大于该价值的体积即可。

    PS:一开始无限的wa,主要有俩个原因,一个是题意理解错了,忽略了选中的电站要留一辆tank在那里,所以,我直接将最短的路径保存之后,遍历所有路径求出最小的消耗

    ,还有一个就是数组开小了

    View Code
    #include<iostream>
    #include<algorithm>
    #define MAXN (100+10)
    #define INF 10000000
    using namespace std;
    int g[MAXN][MAXN],n;
    int dist[MAXN],p[MAXN],dp[MAXN*MAXN];
    bool vis[MAXN];
    void dijkstra()
    {
    int i,j,temp,min;
    for(i=1;i<=n;i++)
    {
    vis[i]=false;
    dist[i]=g[0][i];
    }
    for(i=1;i<n;i++)
    {
    min=INF;
    for(j=1;j<=n;j++)
    if(!vis[j] && dist[j]<min)
    {
    temp=j;
    min=dist[j];
    }
    if(min==INF)
    break;
    vis[temp]=true;
    for(j=1;j<=n;j++)
    if(!vis[j] && dist[j]>dist[temp]+g[temp][j])
    dist[j]=dist[temp]+g[temp][j];
    }
    }
    int main()
    {
    int T,m,a,b,c;
    scanf("%d",&T);
    while(T--)
    {
    scanf("%d %d",&n,&m);
    for(int i=0;i<=n;i++)
    for(int j=0;j<=n;j++)
    {
    if(i==j) g[i][j]=0;
    else
    g[i][j]=INF;
    }
    while(m--)
    {
    scanf("%d %d %d",&a,&b,&c);
    if(c<g[a][b])
    g[a][b]=g[b][a]=c;
    }
    for(int i=1;i<=n;i++)
    scanf("%d",&p[i]);
    int w=0,sum=0;
    dijkstra();
    bool flag=true;
    for(int i=1;i<=n;i++)
    {
    w+=p[i];
    sum+=dist[i];
    if(dist[i]==INF)
    {
    flag=false;
    break;
    }
    }
    if(!flag)
    {
    printf("impossible\n");
    continue;
    }
    for(int i=0;i<=sum;i++)
    dp[i]=0;
    for(int i=1;i<=n;i++)
    for(int j=sum;j>=dist[i];j--)
    dp[j]=max(dp[j],dp[j-dist[i]]+p[i]);
    w=w/2+1;
    for(int i=1;i<=sum;i++)
    if(dp[i]>=w)
    {
    printf("%d\n",i);
    break;
    }
    }
    return 0;
    }
  • 相关阅读:
    PHP常见问题总结
    Java常见问题总结(二)
    C语言常见问题总结
    C#常见问题总结(三)
    C#常见问题总结(二)
    Android常见问题总结(二)
    日期和时间类函数
    Eclipse开发工具介绍
    JavaScript中逻辑运算符的使用
    多路开关模式的switch语句
  • 原文地址:https://www.cnblogs.com/nanke/p/2365969.html
Copyright © 2011-2022 走看看