PAT 1018. Public Bike Management (dijkstra + dfs + 剪枝)
2014-05-07 12:24
639 查看
If there are more than one shortest path, the one that requires
the least number of bikes sent from PBMC will be chosen.
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.
因上述两个要求,光用贪心的dijkstra是不正确的。
1. dijkstra求最短路
2. dfs求出符合上述要求的路径。这个比较花心思。
3. 测试点9可能超时,需要在深搜时剪枝
4. 注意到N是500.. 之前数组开成100了 —— 测试点9是大数据测试
5. 测试用例附在代码后面
代码:
测试用例:
10 3 3 3
6 7 0
0 1 1
0 2 1
0 3 3
10 3 3 3
6 7 9
0 1 1
0 2 1
0 3 3
10 5 5 6
8 7 0 0 5
0 1 1
0 2 1
1 3 1
2 4 1
3 5 1
4 5 1
10 5 5 6
3 4 7 6 5
0 1 1
0 2 1
1 3 1
2 4 1
3 5 1
4 5 1
the least number of bikes sent from PBMC will be chosen.
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.
因上述两个要求,光用贪心的dijkstra是不正确的。
1. dijkstra求最短路
2. dfs求出符合上述要求的路径。这个比较花心思。
3. 测试点9可能超时,需要在深搜时剪枝
dist + map[now.back()][i] <= dis[sp]
4. 注意到N是500.. 之前数组开成100了 —— 测试点9是大数据测试
5. 测试用例附在代码后面
代码:
#include <cstdlib> #include <cstdio> #include <cstring> #include <list> using namespace std; const int INF = 2100000000; int map[505][505]; int cmax, n, sp, m; int has[505], dis[505], ans1, ans2; bool vi[505]; list<int> path, tmp; void init() { scanf("%d%d%d%d", &cmax, &n, &sp, &m); for (int i = 1; i <= n; ++ i) { scanf("%d", has + i); dis[i] = INF; } for (int i = 0; i <= n; ++ i) { for (int j = 0; j <= n; ++ j) { map[i][j] = map[j][i] = INF; } } ans1 = ans2 = INF; while (m --) { int x, y, dis; scanf("%d%d%d", &x, &y, &dis); map[x][y] = map[y][x] = dis; } } void dijkstra() { memset(vi, 0, sizeof(vi)); dis[0] = 0; for (int i = 0; i <= n; ++ i) { int v = -1, minn = INF; for (int j = 0; j <= n; ++ j) { if (dis[j] < minn && vi[j] == false) { v = j; minn = dis[j]; } } if (v == -1) { break; } vi[v] = true; for (int j = 1; j <= n; ++ j) { if (dis[j] > dis[v] + map[v][j]) { dis[j] = dis[v] + map[v][j]; } } } } bool not_in(int city, list<int>& now) { for (auto it = now.begin(); it != now.end(); ++ it) { if (*it == city) { return false; } } return true; } void dfs(list<int>& now, int dist) { if (now.empty() == true) { for (int i = 1; i <= n; ++ i) { if (map[0][i] <= dis[sp]) { now.push_back(i); dfs(now, dist + map[0][i]); now.pop_back(); } } return ; } if (now.back() == sp) { // printf("lookat here\n"); int send_from = 0, take_back = 0; for (auto it = now.begin(); it != now.end(); ++ it) { if (cmax/2 - has[*it] > take_back) { send_from += cmax/2 - has[*it] - take_back; take_back = 0; } else if (cmax/2 - has[*it] > 0 && cmax/2 - has[*it] <= take_back) { take_back -= cmax/2 - has[*it]; } else if (cmax/2 - has[*it] <= 0) { take_back -= cmax/2 - has[*it]; // 其实是加上了一些车 } } if (ans1 > 0 && send_from < ans1) { ans1 = send_from; ans2 = take_back; path = now; } if (ans1 == send_from && take_back < ans2) { // ans1 = send_from; ans2 = take_back; path = now; } return ; } for (int i = 1; i <= n; ++ i) { if (map[now.back()][i] != INF && dist + map[now.back()][i] <= dis[sp] && not_in(i, now)) { int v = now.back(); now.push_back(i); dfs(now, dist + map[v][i]); now.pop_back(); } } } void print() { printf("%d 0", ans1); for (auto it = path.begin(); it != path.end(); ++ it) { printf("->%d", *it); } printf(" %d\n", ans2); } int main() { init(); dijkstra(); dfs(tmp, 0); print(); return 0; }
测试用例:
10 3 3 3
6 7 0
0 1 1
0 2 1
0 3 3
10 3 3 3
6 7 9
0 1 1
0 2 1
0 3 3
10 5 5 6
8 7 0 0 5
0 1 1
0 2 1
1 3 1
2 4 1
3 5 1
4 5 1
10 5 5 6
3 4 7 6 5
0 1 1
0 2 1
1 3 1
2 4 1
3 5 1
4 5 1
相关文章推荐
- PAT - 甲级 1111. Online Map (30)(Dijkstra+DFS)
- 【PAT 1002 All Roads Lead to Rome】+ dfs + dijkstra
- pat 1018. Public Bike Management (dijkstra+dfs)
- PAT-1018 Public Bike Management(dijkstra + dfs)
- 1111. Online Map (30)-PAT甲级真题(Dijkstra + DFS)
- PAT-4C-L3-001-凑零钱(DFS剪枝)
- *浙大PAT甲级 1087 dijkstra+dfs
- PAT甲级1003---迷宫问题(DFS或Dijkstra)
- PAT - 甲级 - 1018. Public Bike Management (30)(Dijkstra+DFS)
- 【PAT 1001 Public Bike Management (30)】+ dfs + dijkstra
- PAT - 甲级 - 1087. All Roads Lead to Rome (30)(Dijkstra+DFS+路径)
- PAT (Advanced Level) 1072. Gas Station (30) Dijkstra最短路径+剪枝
- PAT 1018. Public Bike Management (30)(Dijkstra,dfs根据pre[]输出路径,双向计算)
- PAT (Advanced Level) 1087. All Roads Lead to Rome (30) 条条大路通罗马 Dijkstra+DFS
- PAT - 甲级 - 1030. Travel Plan (30) (Dijkstra+DFS)
- PAT (Advanced Level) 1068. Find More Coins (30) DFS+剪枝 或 动态规划
- 1030. Travel Plan (30)-PAT甲级真题(Dijkstra + DFS,输出路径,边权)
- 1087. All Roads Lead to Rome (30)-PAT甲级真题-Dijkstra + DFS
- 1018. Public Bike Management (30)-PAT甲级真题(Dijkstra + DFS)
- hdu1455 && poj1011 Sticks(深度优先搜索 DFS 经典剪枝 详解)