• 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);
          }
       }
    }
  • 相关阅读:
    PowerDesigner设置线风格(直线,折线。。。)
    使用PowerDesigner画ER图详细教程
    UML学习小结
    UML用例图说明
    UML类图基本画法
    Enterprise Architect与startUML表示UML常用图
    手把手教你使用startuml画用例图
    各种图(流程图,思维导图,UML,拓扑图,ER图)简介
    StartUML 各种类图的例子
    StarUML---推荐一款UML工具(很好很强大)
  • 原文地址:https://www.cnblogs.com/VividBinGo/p/12267302.html
Copyright © 2020-2023  润新知