PAT甲级1018留坑——第一个测试点未过(Dijikstar+Dfs)
题目分析:
主要是先进行狄杰斯特拉求出0点到每个点的最短路后用dfs求出所有的路径,将路径方案加入vector排序选择need最小和rest最小的方案,但是第一个测试却过不去,欢迎指正!!感谢!!
值得注意的是对于一条路径上的所有点进行调整的时候只能一步一步下来,后来多出的车不能用于调整前面走过的点的数量(很重要)
1 #include<iostream> 2 #include<algorithm> 3 #include<vector> 4 #include<string.h> 5 using namespace std; 6 7 const int M = 0x3f3f3f3f; 8 int c, n, sp, m; 9 int mat[505][505]; 10 int vis[505]; //第一次用于作为求dist记录该点是否到达 第二次用于深搜回溯记录是否走过该点 11 int num[505]; 12 int dist[505]; 13 int les_dist = M; 14 struct Node{ 15 int need; 16 int rest; 17 int distance; 18 vector<int> road; 19 }; 20 21 vector<Node> r; //用于存放多个最短路情况下的行走方案,一个数据结构存放一个方案的信息 22 23 int minn(){ 24 int k = -1; 25 int Min = M; 26 int i; 27 for(i = 1; i <= n; i++){ 28 if(vis[i] == 0 && dist[i] < Min){ 29 Min = dist[i]; 30 k = i; 31 } 32 } 33 return k; 34 } 35 36 void run1(){ 37 int i; 38 for(i = 0; i <= n; i++){ //将从0点开始到其他点的距离设为到该点的最小值 39 dist[i] = mat[0][i]; 40 } 41 for(i = 1; i <= n; i++){ //包含0点则有n+1个点 需要进行n次查询 42 int k = minn(); 43 if(k == -1) break; //查询次数未用完但k==-1则代表图不连通 退出循环 44 vis[k] = 1; 45 int j; 46 for(j = 1; j <= n; j++){ 47 if(vis[j] == 0 && dist[k] + mat[k][j] < dist[j]){ 48 dist[j] = dist[k] + mat[k][j]; 49 } 50 } 51 } 52 les_dist = dist[sp]; //全局变量les_dist存放到达终点的最短路径 53 } 54 55 void dfs(Node s, int x){ 56 //对于当前点x来说 需要判断此时存放路径数据的长度加到达x的长度和最短路径长度的关系 57 int pre = s.road.back(); //前一个点 58 if(s.distance + mat[pre][x] <= les_dist){ 59 s.distance += mat[pre][x]; 60 if(num[x] < c/2){ //需要对该点的自行车的数量进行调整 61 if(s.rest >= c/2 - num[x]){ 62 s.rest -= (c/2 - num[x]); 63 }else{ //剩余的不够 64 s.need += c/2 - num[x] - s.rest; //需要的总数减去有的总数则为需要从0点发出的数量 65 s.rest = 0; 66 } 67 }else if(num[x] > c/2){ 68 s.rest += num[x] - c/2; //对多余的车都放入rest中 69 } 70 s.road.push_back(x); //将x加入已经走过的点的队列 71 //当点加完之后判断是否到了终点 72 if(x == sp){ 73 r.push_back(s); //将s这个路径选择方案加入vector r 74 } 75 } 76 if(sp == x) return; 77 vis[x] = 1; 78 int i; 79 for(i = 1; i <= n; i++){ 80 if(vis[i] == 0 && mat[x][i] != M){ 81 dfs(s, i); 82 vis[i] = 0; 83 } 84 } 85 } 86 87 bool cmp(Node a, Node b){ 88 if(a.need != b.need) a.need < b.need; 89 else{ 90 return a.rest < b.rest; 91 } 92 } 93 94 void run2(){ 95 memset(vis, 0, sizeof(vis)); //此次的vis需要重新清零 96 Node s; 97 s.need = 0; 98 s.rest = 0; 99 s.distance = 0; 100 s.road.push_back(0); //将0点作为起始点 101 dfs(s, 0); //从0点开始 其中s为当前存放路径数据的数据结构 102 sort(r.begin(), r.end(), cmp); 103 Node ans = r.front(); 104 if(sp != 0){ 105 printf("%d ", ans.need); 106 int i; 107 for(i = 0; i < ans.road.size(); i++){ 108 if(i != 0) printf("->"); 109 printf("%d", ans.road[i]); 110 } 111 printf(" %d\n", ans.rest); 112 }else{ 113 printf("0 0 0\n"); 114 } 115 } 116 117 int main(){ 118 scanf("%d%d%d%d", &c, &n, &sp, &m); 119 memset(mat, M, sizeof(mat)); 120 memset(vis, 0, sizeof(vis)); 121 int i; 122 for(i = 1; i <= n; i++){ //输入没个点的自行车数量 123 scanf("%d", &num[i]); 124 } 125 for(i = 0; i < m; i++){ 126 int x, y, z; 127 scanf("%d%d%d", &x, &y, &z); 128 mat[x][y] = z; 129 mat[y][x] = z; 130 } 131 run1(); //这部分完成了从起点到sp点的最短路径的计算 132 run2(); //通过bfs查询出通路然后加入vector 133 return 0; 134 }
如果有任何意见请在评论区积极留言