PAT 1018. Public Bike Management (dijkstra + dfs + 剪枝)

来源:互联网 发布:淘宝店工商注册 编辑:程序博客网 时间:2024/05/29 11:43

 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可能超时,需要在深搜时剪枝

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

0 0
原创粉丝点击