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
- PAT 1018. Public Bike Management
- 【PAT】1018. Public Bike Management
- 【PAT】1018. Public Bike Management
- PAT 1018. Public Bike Management
- PAT 1018. Public Bike Management
- 1018. Public Bike Management (30)-PAT
- PAT A 1018.Public Bike Management (30)
- pat 1018. Public Bike Management (30)
- PAT 1018. Public Bike Management (30)
- PAT 1018. Public Bike Management (30)
- PAT 1018. Public Bike Management (30)
- 【PAT】1018. Public Bike Management (30)
- PAT 1018. Public Bike Management (30)
- PAT(A) - 1018. Public Bike Management (30)
- 【PAT甲级】1018. Public Bike Management (30)
- PAT 1018. Public Bike Management (30)
- PAT甲级1018. Public Bike Management (30)
- 1018. Public Bike Management (30) PAT 甲级
- Truncate与Delete的区别
- listview 中 adapter 的getItem 和getItemId方法的作用
- 唐山自闭症怎么治
- 提升销量技巧
- [倚天屠龙记] vim 复制与粘贴
- PAT 1018. Public Bike Management
- @RequestParam的作用
- 一、Unity3D 5.0.1-示例项目“汽车游戏”的展示及开发准备
- 【项目管理和构建】十分钟教程,eclipse配置maven + 创建maven项目(三)
- stvd ubsct溢出错误解决
- 阿里巴巴历年笔试面试70题 [6-10]
- 到入struts之后更改web.xml配置文件之后出现404错误
- 一些開源圖表Chart資源收集(台湾省某网站搜集转载)
- 唐山自闭症去哪家yiyuan