zoukankan      html  css  js  c++  java
  • In Action HDU3339

    这是最短路问题和01背包问题的相结合

    第一次用01背包

    把j打成了i检查了半个小时  下次要注意!

    使用的油耗相当于容量  而power相当于价值

    先用dijkstra把从基地到所有路的最短情况算出来

    然后开始01背包

    所有最短路的油耗相加就是总的容量

    然后开始dp【j】 算出油耗为j时能获取的最大power

    大于总的power的一半时输出

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <string>
    #include<cstdio>
    using namespace std;
    
    #define INF 0x3f3f3f3f
    #define M 110
    
    int m1[M][M];
    int dis[M];
    int vis[M];
    int n;
    int v[M];
    
    
    void dijkstra()
    {
        memset(vis,0,sizeof(vis));
    
        for(int i=1;i<=n;i++)dis[i]=INF;
        dis[0]=0;
        vis[0]=1;
        for(int i=1;i<=n;i++)
        {
          int minn=INF;
          int u=0;
          for(int j=0;j<=n;j++)
          {
              if(!vis[j]&&minn>dis[j])
              {
                  u=j;minn=dis[j];
              }
    
          }
           vis[u]=1;
           for(int j=0;j<=n;j++)
           {
    
               if(!vis[j]&&dis[u]+m1[u][j]<dis[j])
                  dis[j]=dis[u]+m1[u][j];
    
           }
    
    
        }
    
    
    
    }
    
    
    
    int main()
    {
      int cas;scanf("%d",&cas);
      while(cas--)
      {
          int m;
          scanf("%d%d",&n,&m);
          for(int i=0;i<=n;i++)
            for(int j=0;j<=n;j++)
          {
              if(i==j)m1[i][j]=0;
              else m1[i][j]=INF;
          }
    
          while(m--)
          {
              int a,b,c;
              scanf("%d%d%d",&a,&b,&c);
              if(m1[a][b]>c)m1[a][b]=m1[b][a]=c;
    
          }
    
    
    
          int sumpower=0;
          for(int i=1;i<=n;i++)
          {
              int x;scanf("%d",&x);
              v[i]=x;
              sumpower+=x;
          }
            sumpower/=2;
          dijkstra();
    
    
          int dp[100000]={0};
          memset(dp,0,sizeof(dp));
          int oil=0;
          for(int i=1;i<=n;i++)
          {
              if(dis[i]!=INF)oil+=dis[i];
          }
    
          for(int i=1;i<=n;i++)
          {
              if(dis[i]!=INF)
              {
    
                  for(int j=oil;j>=dis[i];j--)
                  {
    
                      dp[j]=max(dp[j],dp[ j-dis[i]  ]+v[i]);
    
                  }
              }
    
    
          }
          int ok=1;int i;
          for( i=0;i<=oil;i++)
           {
               if(dp[i]>sumpower)
               {
                   ok=0;break;
               }
    
           }
          if(ok)
             printf("impossible
    ");
          else
            printf("%d
    ",i);
    
      }
        return 0;
    
    
    }
    View Code

    回顾

    #include<iostream>
    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    using namespace std;
    
    #define N 110
    #define inf 0x3f3f3f3f
    int dp[100000];
    
    int n,e,m,s;
    int vis[N],dis[N],mp[N][N];
    int power[N];
    
    
    void dijkstra(int s)
    {
        memset(vis,0,sizeof vis);
        for(int i=0;i<=n;i++)dis[i]=mp[s][i];
        dis[s]=0;
    
        for(int i=0;i<=n;i++)
        {
            int minn=inf,u=-1;
    
            for(int j=1;j<=n;j++)
                if(dis[j]<minn&&!vis[j])
                    {
                        minn=dis[j];u=j;
                    }
           if(u==-1)return ;
            vis[u]=1;
            for(int j=1;j<=n;j++)
                dis[j]=min(dis[j],dis[u]+mp[u][j]);
        }
    }
    
    int main()
    {
        int cas;cin>>cas;
        while(cas--)
        {
            scanf("%d%d",&n,&m);
            for(int i=0;i<=n;i++)
                for(int j=0;j<=n;j++)
            {
                if(i==j)mp[i][j]=0;
                else  mp[i][j]=inf;
            }
            long long oil=0;
            while(m--)
            {
                int a,b,c;
                scanf("%d%d%d",&a,&b,&c);
    
                if(mp[a][b]>c)mp[a][b]=mp[b][a]=c;
    
            }
            int sum=0;
            for(int i=1;i<=n;i++)
                {
                 scanf("%d",&power[i]);
                 sum+=power[i];
                 }
    
            dijkstra(0);
            //背包   价值为能量    容量为耗油
           for(int i=1;i<=n;i++)
                if(dis[i]!=inf)oil+=dis[i];
    
          memset(dp,0,sizeof dp);
    
         for(int i=1;i<=n;i++)
          for(int j=oil;j>=dis[i];j--)
                dp[j]=max(dp[j],dp[j-dis[i]]+power[i]);
         sum/=2;
         int i;
         for(i=1;i<=oil;i++)
            if(dp[i]>sum)
           {
             printf("%d
    ",i);break;
           }
          if(i==oil+1)
            printf("impossible
    ");
        }
        return 0;
    }
  • 相关阅读:
    虚拟化VMware之虚拟机备份(1)
    虚拟化VMware之虚拟机备份(1)
    柯塔娜大合唱,互联网安全观
    柯塔娜大合唱,互联网安全观
    如何在虚拟机上Centos系统安装Nginx服务
    给已验证登录的用户添加访问限制
    Python爬虫入门教程 23-100 石家庄链家租房数据抓取
    login_required装饰器(1)
    Oracle 18c 新特性:动态 Container Map 增强 Application Container 灵活性
    如果登录不成功,跳转到登录页面
  • 原文地址:https://www.cnblogs.com/bxd123/p/10330502.html
Copyright © 2011-2022 走看看