PAT 甲级-1018 Public Bike Management (30)(好题)(30 分)

题目大意:

每个自行车车站的最大容量为一个偶数cmax,如果一个车站里面自行车的数量恰好为cmax / 2,那么称处于完美状态。如果一个车展容量是满的或者空的,控制中心(处于结点0处)就会携带或者从路上手机一定数量的自行车前往该车站,一路上会让所有的车展沿途都达到完美。现在给出cmax,车站的数量n,问题车站sp,m条边,还有距离,求最短路径。如果最短路径有多个,求能带的最少的自行车数目的那条。如果还是有很多条不同的路,那么就找一个从车站带回的自行车数目最少的。带回的时候是不调整的

比较经典的Dijkstra。有优先级的Dijkstra,还要加一个DFS遍历所有的路径,并选出最优的路径。首先在Dijkstra的基础上记录路径,用vector来存,edge【x】表示哪些点到x的距离最短(可能有多个)。最后DFS求出每一条路径需要带出的自行车数量和带回的自行车数量。具体的代码中解释。

这类的题目还是比较多的,好像都是30分的。。。有的不需要DFS,有的需要用map做个映射,代码相对会长一点。

1030 Travel Plan (30)(30 分)

1072 Gas Station (30)(30 分)

1087 All Roads Lead to Rome (30)(30 分)

1111 Online Map (30)(30 分)

#include
using namespace std;
typedef long long LL;
const int inf=1e9;
int a[505][505];
int v[505],d[505],vis[505];
vectoredge[505],path,tpath;
int C,n,e,m;
int mingo,aback;
void dfs(int x)
{
    tpath.push_back(x);
    if(x==0)
    {
        int len=tpath.size();
        int tgo=0,tback=0;  // 带来和带回的数量。
        for(int i=len-2;i>=0;i--)
        {
           // cout<=C/2) //当前站点和要带回的和大于要求的数量。
            {                              
                tback=v[tpath[i]]+tback-C/2;
            }
            else
            {
                tgo+=(C/2-v[tpath[i]]-tback); //当前站点和要带回的和不够要求的数量。
                tback=0;                     // 则必须从0站点带来,带回的更新为0.
            }
        }
       // cout<<"-----";
       // cout<tback)
        {
            aback=tback;
            path=tpath;
        }
        tpath.pop_back();
        return;
    }
    for(int i=0;i>C>>n>>e>>m;
    for(int i=1;i<=n;i++) cin>>v[i];
    for(int i=0;i<=n;i++)
    {
        vis[i]=0;
        for(int j=0;j<=n;j++)
         a[i][j]=inf;
    }
    while(m--)
    {
        int x,y,z;
        cin>>x>>y>>z;
        a[x][y]=a[y][x]=min(a[x][y],z);
    }
    for(int i=1;i<=n;i++)
        d[i]=a[0][i];
        d[0]=0;
    for(int j=0;j<=n;j++)
    {
        int tmp=inf,pos;
        for(int i=0;i<=n;i++)
        {
            if(vis[i]==0&&tmp>d[i])
            {
                tmp=d[i];
                pos=i;
            }
        }
        vis[pos]=1;
        for(int i=1;i<=n;i++)
        {
            if(vis[i]==0&&a[pos][i]!=inf)
            {
                if(d[i]>d[pos]+a[pos][i])
                {
                    d[i]=d[pos]+a[pos][i];
                    edge[i].clear();
                    edge[i].push_back(pos); // 如果经过pos到i站点使得距离更小,
                                             //  则更新,把之前的前驱清空
                }
                else if(d[i]==d[pos]+a[pos][i])
                {
                    edge[i].push_back(pos);  //如果经过pos到i站点使得距离与最小的一样,
                                                // 则插入。
                }
            }
        }
    }
    mingo=aback=inf;
    dfs(e);
    cout<=0;i--) cout<<"->"<

你可能感兴趣的:(PAT 甲级-1018 Public Bike Management (30)(好题)(30 分))