【PAT甲級】Public Bike Management 題解


    • 題目描述

      There is a public bike service in Hangzhou City which provides great convenience to the tourists from all over the world.  One may rent a bike at any station and return it to any other stations in the city.
      The Public Bike Management Center (PBMC) keeps monitoring the real-time capacity of all the stations. A station is said to be in perfect condition if it is exactly half-full. If a station is full or empty, PBMC will collect or send bikes to adjust the condition of that station to perfect. And more, all the stations on the way will be adjusted as well.
      When a problem station is reported, PBMC will always choose the shortest path to reach that station. If there are more than one shortest path, the one that requires the least number of bikes sent from PBMC will be chosen.

      Figure 1
      Figure 1 illustrates an example.  The stations are represented by vertices and the roads correspond to the edges.  The number on an edge is the time taken to reach one end station from another.  The number written inside a vertex S is the current number of bikes stored at S.  Given that the maximum capacity of each station is 10.  To solve the problem at S3, we have 2 different shortest paths:
      1. PBMC -> S1 -> S3. In this case, 4 bikes must be sent from PBMC, because we can collect 1 bike from S1 and then take 5 bikes to S3, so that both stations will be in perfect conditions.
      2. PBMC -> S2 -> S3. This path requires the same time as path 1, but only 3 bikes sent from PBMC and hence is the one that will be chosen.

      輸入描述:

      Each input file contains one test case.  For each case, the first line contains 4 numbers: Cmax (<= 100), always an even number, is the maximum capacity of each station; N (<= 500), the total number of stations; Sp, the index of the problem station (the stations are numbered from 1 to N, and PBMC is represented by the vertex 0); and M, the number of roads.  The second line contains N non-negative numbers Ci (i=1,...N) where each  Ci is the current number of bikes at Si respectively.  Then M lines follow, each contains 3 numbers: Si, Sj, and Tij which describe the time Tij taken to move betwen stations Si and Sj.  All the numbers in a line are separated by a space.


      輸出描述:

      For each test case, print your results in one line.  First output the number of bikes that PBMC must send.  Then after one space, output the path in the format: 0->S1->...->Sp.  Finally after another space, output the number of bikes that we must take back to PBMC after the condition of Sp is adjusted to perfect.
      Note that if such a path is not unique, output the one that requires minimum number of bikes that we must take back to PBMC. The judge's data guarantee that such a path is unique.

      輸入例子:

      10 3 3 5
      6 7 0
      0 1 1
      0 2 1
      0 3 3
      1 3 1
      2 3 1

      輸出例子:

      3 0->2->3 0


    • 題目要求:
    • 從PMBC出發,到終點Sp,找出一條最短的路徑,並將路徑上的每個站單車數量調整到最佳狀態(即半滿)。這需要你從PMBC攜帶一些車出發,調整路上的每個站的單車,少則補,多則帶走,到終點可能還需帶回一些單車。如果最短的路徑有多條,選需要送去的車最少的一條;如果需要送去的車一樣少的路徑還不止一條,選需要帶回的車最少的一條,保證這種情況只有一條路徑。最后要輸出需要送去的單車數,這條路徑經過的每個站,以及最后要帶回的單車數

    • 解題方法:
      這道題可以使用深搜結合回溯算法,從PMBC(節點0)開始搜索,找出最終符合條件的路徑,並用vector存儲路徑,最后輸出,代碼如下:

       1 #include <iostream>
       2 #include <vector>
       3 using namespace std;
       4 
       5 int cmax,n,sp,m;
       6 int bike[505];
       7 int route[505][505];
       8 int visit[505];
       9 int minsend,minback,mindis;
      10 vector<int> path,npath;    //path記錄最后結果的路徑,npath記錄求解過程中的路徑
      11 
      12 void dfs(int v,int nsend,int nback,int ndis){    //當前訪問節點v,需要送來的總車輛nsend,需要帶回的總車輛nback,需要的總路程ndis
      13     int i;
      14     int send,back,state;
      15 
      16     visit[v]=1;
      17     npath.push_back(v);
      18 
      19     if(sp==v){    //到達終點
      20         if(ndis<mindis){    //路程最短
      21             path=npath;
      22             minsend=nsend;
      23             minback=nback;
      24             mindis=ndis;
      25         }
      26         else if(ndis==mindis){
      27             if(nsend<minsend){    //需要送來的車最少
      28                 path=npath;
      29                 minsend=nsend;
      30                 minback=nback;
      31             }
      32             else if(nsend==minsend && nback<minback){    //需要返回的車最少
      33                 path=npath;
      34                 minback=nback;
      35             }
      36         }
      37         return;
      38     }
      39 
      40     for(i=1;i<=n;i++){    //訪問下一個節點
      41         if(visit[i]==0 && route[v][i]!=-1){    //未被訪問且可訪問
      42             state=bike[i]-cmax;    //判斷該節點的狀態,為正表示需要帶回車輛,為負表示需要送車輛
      43             send=nsend;
      44             back=nback;
      45             if(state>=0)    back+=state;
      46             else{
      47                 if(nback+state<0){    //若前面返回的車輛足夠供給該節點,則從返回的車輛中取
      48                     send-=(nback+state);
      49                     back=0;
      50                 }
      51                 else back+=state;
      52             }
      53             dfs(i,send,back,ndis+route[v][i]);
      54             npath.pop_back();
      55             visit[i]=0;
      56         }
      57     }
      58 }
      59 
      60 int main(){
      61 
      62     int i,j;
      63     int x,y,z;
      64     unsigned int k;
      65 
      66     scanf("%d%d%d%d",&cmax,&n,&sp,&m);
      67     cmax/=2;    //perfect狀態
      68 
      69     for(i=0;i<n;i++)    scanf("%d",&bike[i+1]);
      70     
      71     for(i=0;i<=n;i++)
      72         for(j=0;j<=n;j++)
      73             if(i==j)    route[i][j]=0;
      74             else route[i][j]=-1;    //邊預處理
      75     for(i=0;i<m;i++){
      76         scanf("%d%d%d",&x,&y,&z);
      77         route[x][y]=route[y][x]=z;
      78     }
      79 
      80     for(i=0;i<=n;i++)    visit[i]=0;
      81     minsend=minback=mindis=100007;
      82     
      83     dfs(0,0,0,0);
      84 
      85     printf("%d ",minsend);
      86     for(k=0;k < path.size();k++){
      87         if(k!=0)    printf("->");
      88         printf("%d",path[k]);
      89     }
      90     printf(" %d",minback);
      91 
      92     return 0;
      93 }

       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM