PAT 1018 Public Bike Management —Dijkstra+dfs筛选

题解

原题链接
这题我一开始没读懂题意,其实题目意思是这样的,给你一个需要调整的位置然后你需要找一条从PBMC(0位置点)到给定位置的最短路径,这个最短路径可能有多条
注意点:

  1. 从PBMC到给定位置,其路径所经过点都需要调整到perfect
  2. 不能返回的时候再调整,多的自行车可以带回
  3. 最短路径有多条的时候优先选择从PBMC带出自行车最少的那一条,如果还有多条就选择最终返回所带自行车数目最少的,题目保证这样的路径只有一条

解题思路:

  • Dijkstra首先保存所有的最短路径
  • dfs一遍,筛选出最优解

AC代码

#include <cstdio>
#include <vector>
#include <algorithm>
#define maxn 510
#define inf 1e9

using namespace std;

void dijkstra();
void dfs(int v);

struct Edge
{
   int to;
   int cost;
};

int C, N, S, M;
int v[maxn], dist[maxn], cap[maxn], minout=inf, minback=inf;
bool vis[maxn];
vector<Edge> E[maxn];
vector<int> pre[maxn], tempath, path;

int main()
{
   fill(dist, dist+maxn, inf);
   fill(vis, vis+maxn, false);
   scanf("%d %d %d %d",&C, &N, &S, &M);
   for (int i=1; i<=N; i++)
   {
       scanf("%d",&cap[i]);
       cap[i] -= C/2;
   }
   for (int i=1; i<=M; i++)
   {
       int v1, v2, cost;
       Edge e1, e2;
       scanf("%d %d %d",&v1, &v2, &cost);
       e1.to = v2;
       e1.cost = cost;
       e2.to = v1;
       e2.cost = cost;
       E[v1].push_back(e1);
       E[v2].push_back(e2);
   }
   dijkstra();
   dfs(S);
   printf("%d ",minout);
   for (int i=path.size()-1; i>0; i--)
       printf("%d->", path[i]);
   printf("%d %d",path[0],minback);
   printf("\n%d",sizeof vis);
   return 0;
}

void dijkstra()
{
   for (int i=0; i<E[0].size(); i++)
   {
       dist[E[0][i].to] = E[0][i].cost;
       pre[E[0][i].to].push_back(0);
   }
   vis[0] = true;
   for (int vertex=1; vertex<=N; vertex++)
   {
       int MIN=inf, u=-1, v, cost;
       for(int i=1; i<=N; i++)
       {
           if (vis[i]==false&&dist[i]<MIN)
           {
               MIN = dist[i];
               u = i;
           }
       }
       if (u==-1)
           return;
       vis[u] = true;
       for (int i=0; i<E[u].size(); i++)
       {
           v = E[u][i].to;
           cost = E[u][i].cost;
           if (vis[v] == false)
           {
               if (dist[u]+cost < dist[v])
               {
                   dist[v] = dist[u]+cost;
                   pre[v].clear();
                   pre[v].push_back(u);
               }
               else if (dist[u]+cost == dist[v])
                   pre[v].push_back(u);
           }
       }
   }
}

void dfs(int v)
{
   tempath.push_back(v);
   if (v==0)
   {
      int nowhave=0, takeout=0;
      for (int i=tempath.size()-1; i>=0; i--)
      {
          if(cap[tempath[i]] >= 0)
           nowhave += cap[tempath[i]];
          else
          {
              if (nowhave+cap[tempath[i]] >= 0)
                   nowhave += cap[tempath[i]];
              else
              {
                  takeout -= (nowhave+cap[tempath[i]]);
                  nowhave = 0;
              }
          }
      }
      if (takeout < minout)
      {
          path = tempath;
          minout = takeout;
          minback = nowhave;
      }
      else if (takeout == minout && nowhave < minback)
      {
          path = tempath;
          minback = nowhave;
      }
      tempath.pop_back();
      return;
   }
   for (int i=0; i<pre[v].size(); i++)
       dfs(pre[v][i]);
   tempath.pop_back();
}

end

猜你喜欢

转载自blog.csdn.net/adventural/article/details/86771948