PAT 1018. Public Bike Management

来源:互联网 发布:nginx php cgi 配置 编辑:程序博客网 时间:2024/05/21 09:37

【题目链接】

这题就是先求最短路径,当有多条最短路径的时候按照如下原则择优:sent的自行车较少的更优,如果sent的自行车数量相同,则take back的自行车数量最少的更优。

第一次提交的时候只过了4个case,原因在于:只要前面station的自行车数量不足,就必须从PBMC派送自行车,无论后面路径上的自行车数量是否有多余,也就是说是一个不可逆转的过程。后来改写了程序,在Dijkstra算法的基础上,逐步地对sentBike和backBike进行累加,提交后第7个case不过,无奈之下只好百度,发现不能再Dijkstra的时候同时更新自行车的sentBike和backBike,因为它们不满足最优子结构性质。只能用Dijkstra算出最短距离,然后用dfs搜索最优路径。

第7个case不过的程序:

//第7个case不过,因为不满足最优子结构,不能将sentBike简单的累加#include <iostream>#include <vector>#include <algorithm>#include <cstdio>using namespace std;const int INF = 10000000;const int MAXV = 505;int Cmax, N, Sp, M;int sentBike[MAXV] = {0}, backBike[MAXV] = {0};int d[MAXV]; //最短距离数组int C[MAXV]; //C[i]表示第i个station的自行车数量int path[MAXV]; //path[i]存放第i个点的前驱顶点int G[MAXV][MAXV]; //图的邻接矩阵bool vis[MAXV] = {false}; //标记顶点是否被访问void Dijkstra(){    d[0] = 0, path[0] = -1, C[0] = 0;    for(int i = 0; i <= N; i++)    {        int u = -1, MIN = INF;        for(int j = 0; j <= N; j++)        {            if(!vis[j] && d[j] < MIN)                MIN = d[u = j];        }        if( u == -1) return;        vis[u] = true;        for(int v = 0; v <= N; v++)            if(!vis[v])            {                int count = Cmax / 2 - C[v];                if(d[u] + G[u][v] == d[v])                {                    if(sentBike[u] + max(0, count) < sentBike[v])                    {                        sentBike[v] = sentBike[u] + max(0, count); //更新sentBike[v]                        path[v] = u;                    }                    else if(sentBike[u] + max(0, count) == sentBike[v])                    {                        if(backBike[u] - min(0, count) < backBike[v])                        {                            backBike[v] = backBike[u] - min(0, count);//更新backBike[v]                            path[v] = u;                        }                    }                }                else if(d[u] + G[u][v] < d[v])                {                    d[v] = d[u] + G[u][v];                    path[v] = u;                    if(count >= 0)                    {                        if(backBike[u] - count > 0)                        {                            backBike[v] = backBike[u] - count;                            sentBike[v] = sentBike[u];                        }                        else                        {                            backBike[v] = 0;                            sentBike[v] = sentBike[u] + count - backBike[u];                        }                    }                    else                    {                        sentBike[v] = sentBike[u];                        backBike[v] = backBike[u] - count;                    }                }            }    }}void output(){    vector<int> vi;    int u = Sp;    while(path[u] != -1)    {        vi.push_back(u);        u = path[u];    }    vi.push_back(0);    cout << sentBike[Sp] << " ";    for(int i = vi.size() - 1; i >=0; i--)    {        cout << vi[i];        if(i) cout << "->";    }    cout << " " << backBike[Sp] << endl;}int main(){    //freopen("in_1018.txt", "r", stdin);    cin >> Cmax >> N >> Sp >> M;    for(int i = 1; i <= N; i++)        cin >> C[i];    for(int i = 0; i <= N; i++) //初始化邻接矩阵G        for(int j = 0; j <= N; j++)            G[i][j] = INF;    fill(d, d + MAXV, INF); //初始化距离为无穷大    int start, end, time;    for(int i = 0; i < M; i++)    {        cin >> start >> end >> time;        G[start][end] = G[end][start] = time;    }    Dijkstra();    output();}

全部AC的程序:

#include <iostream>#include <vector>#include <algorithm>#include <cstdio>using namespace std;const int INF = 10000000;const int MAXV = 505;int Cmax, N, Sp, M;int sentBike = INF, backBike = INF;int d[MAXV]; //最短距离数组int C[MAXV]; //C[i]表示第i个station的自行车数量int G[MAXV][MAXV]; //图的邻接矩阵bool vis_dij[MAXV] = {false}; //标记顶点是否被访问bool vis_dfs[MAXV] = {false};int curTime = 0; //当前花费的时间int curSentBike, curBackBike; //当前需要从PBMC派出去的和带回PBMC的自行车数量vector<int> path; //符合条件的最短路径vector<int> curPath; //dfs过程中遍历的路径void Dijkstra(){    d[0] = 0, C[0] = 0;    for(int i = 0; i <= N; i++)    {        int u = -1, MIN = INF;        for(int j = 0; j <= N; j++)            if(!vis_dij[j] && d[j] < MIN)                MIN = d[u = j];        if(u == -1) return;        vis_dij[u] = true;        for(int v = 0; v <= N; v++)            if(!vis_dij[v] && d[u] + G[u][v] < d[v])                d[v] = d[u] + G[u][v];    }}bool judge(vector<int> curPath) //按照题意选择最优的最短路径{    curSentBike = curBackBike = 0;    for(int i = 0; i < curPath.size(); i++)    {        int v = curPath[i];        int count = Cmax / 2 - C[v];        if(count >= 0)        {            if(curBackBike - count > 0) curBackBike -= count;            else            {                curSentBike += count - curBackBike;                curBackBike = 0;            }        }        else curBackBike -= count;    }    //优先选择派出的自行车数量最少的最短路径,其次再选带回最少的最短路径    if(curSentBike != sentBike) return curSentBike < sentBike;    else return curBackBike < backBike;}void dfs(int cur) //深度优先搜索最短路径{    if(cur == Sp)    {        if(curTime == d[Sp] && judge(curPath))        {            path = curPath;            sentBike = curSentBike;            backBike = curBackBike;        }        return;    }    for(int i = 1; i <= N; i++)    {        if(G[cur][i] != INF && !vis_dfs[i])        {            vis_dfs[i] = true;            curPath.push_back(i);            curTime += G[cur][i];            dfs(i);            vis_dfs[i] = false;            curPath.pop_back();            curTime -= G[cur][i];        }    }}void print(){    cout << sentBike << " 0";    for(int i = 0; i < path.size(); i++)        cout << "->" << path[i] ;    cout << " " << backBike << endl;}int main(){    //freopen("in_1018.txt", "r", stdin);    cin >> Cmax >> N >> Sp >> M;    for(int i = 1; i <= N; i++)        cin >> C[i];    for(int i = 0; i <= N; i++) //初始化邻接矩阵G        for(int j = 0; j <= N; j++)            G[i][j] = INF;    fill(d, d + MAXV, INF); //初始化距离为无穷大    int start, end, time;    for(int i = 0; i < M; i++)    {        cin >> start >> end >> time;        G[start][end] = G[end][start] = time;    }    Dijkstra();    dfs(0);    print();}


附件


0 0
原创粉丝点击