• 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;
    }
  • 相关阅读:
    2015531 网络攻防 Exp1 PC平台逆向破解(5)M
    2017-2018-1 20155331 嵌入式C语言
    20155330 《网络对抗》 Exp9 web安全基础实践
    20155330 《网络对抗》 Exp8 Web基础
    20155330 《网络对抗》 Exp7 网络欺诈防范
    20155330 《网络对抗》 Exp6 信息搜集与漏洞扫描
    20155330 《网络对抗》 Exp5 MSF基础应用
    20155330 《网络攻防》 Exp4 恶意代码分析
    20155330 《网络攻防》 Exp3 免杀原理与实践
    20155330 《网络对抗》 Exp2 后门原理与实践
  • 原文地址:https://www.cnblogs.com/bxd123/p/10330502.html
Copyright © 2020-2023  润新知