• PAT (Advanced Level) 1018 Public Bike Management


    题解

      看完这题,直接来一套最短路。这次WA了,淦。

      因为这道题路径的选择条件为:第一标尺是距离短优先,第二标尺是从管理中心带出去的自行车少的优先,第三标尺是从站点带回去的自行车少的优先。

      只用最短路算法解决这道题的话,第二标尺和第三标尺不能被正确维护,因为最短路算法的特点,会出现改变其他站点的自行车数量,但是这个站点并不在你的最终路径上的情况。

      所以正确解法是先利用最短路算法将距离最短的路径(可能不止一条)保存下来,再利用深搜对这些在距离上最优的路径进行第二标尺和第三标尺的筛选,求得最优解。

    错误代码

    #include<bits/stdc++.h>
    using namespace std;
    struct node
    {
        int to,w;
        node(int a,int b)
        {
            to=a;
            w=b;
        }
    };
    vector<node> edge[520];
    int V,N,M,D,bike[520],dis[520],vis[520],path[520],cost[520];
    void spfa();
    void print(int p);
    int main()
    {
        int i,u,v,t;
        scanf("%d%d%d%d",&V,&N,&D,&M);
        V/=2;
        for(i=1;i<=N;i++) scanf("%d",&bike[i]);
        while(M--)
        {
            scanf("%d%d%d",&u,&v,&t);
            edge[u].push_back(node(v,t));
            edge[v].push_back(node(u,t));
        }
        spfa();
        printf("%d ",cost[D]>0?cost[D]:0);
        printf("0");print(D);
        printf(" %d",cost[D]<0?-cost[D]:0);
        system("pause");
        return 0;
    }
    void print(int p)
    {
        if(path[p]==-1) return;
        print(path[p]);
        printf("->%d",p);
    }
    void spfa()
    {
        fill(dis+1,dis+520,0x3fffffff);
        fill(path,path+520,-1);
        queue<int> que;
        int i,from,to,w;
        que.push(0);
        while(!que.empty())
        {
            from=que.front();
            que.pop();
            vis[from]=0;
            for(i=0;i<edge[from].size();i++)
            {
                to=edge[from][i].to;
                w=edge[from][i].w;
                if(dis[to]>dis[from]+w)
                {
                    dis[to]=dis[from]+w;
                    path[to]=from;
                    cost[to]=cost[from]+V-bike[to];
                    if(vis[to]==0)
                    {
                        vis[to]=1;
                        que.push(to);
                    }
                }
                else if(dis[to]==dis[from]+w)
                {
                    if(abs(cost[to])>abs(cost[from]+V-bike[to]))
                    {
                        cost[to]=cost[from]+V-bike[to];
                        path[to]=from;
                    }
                }
            }
        }
    }

    正确代码

    #include<bits/stdc++.h>
    using namespace std;
    struct node
    {
       int to,w;
       node(int a,int b)
       {
          to=a;
          w=b;
       }
    };
    vector<node> edge[520];
    vector<int> ans,temp,path[520];
    int V,N,M,D,bike[520],dis[520],vis[520],mminneed=0x7fffffff,mminback=0x7fffffff;
    void spfa();
    void dfs(int p);
    int main()
    {
        int i,u,v,t;
        scanf("%d%d%d%d",&V,&N,&D,&M);
        for(i=1;i<=N;i++) scanf("%d",&bike[i]);
        while(M--)
        {
            scanf("%d%d%d",&u,&v,&t);
            edge[u].push_back(node(v,t));
            edge[v].push_back(node(u,t));
        }
    
        spfa();
        dfs(D);
    
        printf("%d ",mminneed);
        for(i=ans.size()-1;i>=0;i--)
        {
           if(i!=ans.size()-1) printf("->");
           printf("%d",ans[i]);
        }
        printf(" %d",mminback);
        
        system("pause");
        return 0;
    }
    void dfs(int p)
    {
       int i;
       temp.push_back(p);
       if(p==0)
       {
          int need=0,back=0;
          for(i=temp.size()-2;i>=0;i--)
          {
             if(bike[temp[i]]>=V/2) back=back+bike[temp[i]]-V/2;
             else
             {
                if(back>=V/2-bike[temp[i]]) back=back-V/2+bike[temp[i]];
                else 
                {
                   need=need+V/2-bike[temp[i]]-back;
                   back=0;
                } 
             }
          }
    
          if(need<mminneed)
          {
             mminneed=need;
             mminback=back;
             ans=temp;
          }
          else if(need=mminneed&&back<mminback)
          {
             mminback=back;
             ans=temp;
          }
          
          temp.pop_back();
          return ;
       }
    
       for(i=0;i<path[p].size();i++)
          dfs(path[p][i]);
       
       temp.pop_back();
    }
    void spfa()
    {
       fill(dis+1,dis+520,0x3fffffff);
       queue<int> que;
       int i,from,to,w;
       que.push(0);
       while(!que.empty())
       {
          from=que.front();
          que.pop();
          vis[from]=0;
          for(i=0;i<edge[from].size();i++)
          {
             to=edge[from][i].to;
             w=edge[from][i].w;
             if(dis[to]>dis[from]+w)
             {
                dis[to]=dis[from]+w;
                path[to].clear();
                path[to].push_back(from);
                if(vis[to]==0)
                {
                   vis[to]=1;
                   que.push(to);
                }
             }
             else if(dis[to]==dis[from]+w)
                path[to].push_back(from);
          }
       }
    }
  • 相关阅读:
    asp.net的处理机制(.ashx/.aspx)
    docker使用记录二:mysql安装与配置
    docker使用记录一日常使用的命令
    git笔记十:本地仓库同步到gitlab
    git使用记录九:开发中临时加塞了紧急任务怎么处理
    git使用记录八:不同提交的指定文件的差异
    git使用记录七:对工作区和暂存区的一些操作场景
    git使用记录六:对commit的message做处理
    git使用记录四:.git分析
    git使用记录三:查看日志
  • 原文地址:https://www.cnblogs.com/VividBinGo/p/12267302.html
Copyright © 2020-2023  润新知