题目:https://pintia.cn/problem-sets/994805342720868352/problems/994805358663417856
题意:
给定一个图,每天边上有时间和路程信息。要求找到路程最短且时间最短的路径,和时间最短经过的节点最少的路径。
思路:
和昨天写的那个Public Bike Arrangement差不多思路。但是因为要求两个东西所以麻烦一点。感觉好像PAT也在逐渐变难。
都是先求出最短路路径,然后在这些路径中再找到符合条件的一条。
该开始直接写dfs,最后一组数据T了。
先dijkstra再dfs的话是在最短路径上找,会减很多枝。
1 //#include<bits/stdc++> 2 #include<stdio.h> 3 #include<iostream> 4 #include<algorithm> 5 #include<cstring> 6 #include<stdlib.h> 7 #include<queue> 8 #include<map> 9 #include<stack> 10 #include<set> 11 12 #define LL long long 13 #define ull unsigned long long 14 #define inf 0x7f7f7f7f 15 16 using namespace std; 17 18 const int maxn = 505; 19 int n, m; 20 int st, ed; 21 struct node{ 22 int v; 23 int l, t; 24 node(){} 25 node(int _v, int _l, int _t){ 26 v = _v; 27 l = _l; 28 t = _t; 29 } 30 }; 31 vector<node>g[maxn]; 32 33 bool vis_l[maxn], vis_t[maxn]; 34 int d_len[maxn], d_time[maxn]; 35 void dijkstra() 36 { 37 memset(d_len, 0x3f, sizeof(d_len)); 38 memset(d_time, 0x3f, sizeof(d_time)); 39 for(int i = 0; i < g[st].size(); i++){ 40 int to = g[st][i].v; 41 d_len[to] = g[st][i].l; 42 d_time[to] = g[st][i].t; 43 } 44 vis_l[st] = true; 45 vis_t[st] = true; 46 d_len[st] = 0; 47 d_time[st] = 0; 48 49 for(int i = 1; i < n; i++){ 50 int id_l, id_t; 51 int minl = inf, mint = inf; 52 for(int i = 0; i < n; i++){ 53 if(!vis_l[i] && minl > d_len[i]){ 54 minl = d_len[i]; 55 id_l = i; 56 } 57 if(!vis_t[i] && mint > d_time[i]){ 58 mint = d_time[i]; 59 id_t = i; 60 } 61 } 62 63 vis_l[id_l] = true; 64 vis_t[id_t] = true; 65 for(int i = 0; i < g[id_l].size(); i++){ 66 int to = g[id_l][i].v; 67 if(d_len[to] > d_len[id_l] + g[id_l][i].l){ 68 d_len[to] = d_len[id_l] + g[id_l][i].l; 69 } 70 } 71 for(int i = 0; i < g[id_t].size(); i++){ 72 int to = g[id_t][i].v; 73 if(d_time[to] > d_time[id_t] + g[id_t][i].t){ 74 d_time[to] = d_time[id_t] + g[id_t][i].t; 75 } 76 } 77 } 78 } 79 80 int ans_len = inf, time_for_minlen = inf; 81 int length, ttime; 82 vector<int>minlen, path; 83 bool vis[maxn]; 84 void dfs_len(int pos) 85 { 86 if(pos == ed){ 87 if(ttime < time_for_minlen){ 88 time_for_minlen = ttime; 89 minlen = path; 90 return; 91 } 92 } 93 for(int i = 0; i < g[pos].size(); i++){ 94 int to = g[pos][i].v; 95 if(!vis[to] && d_len[to] == d_len[pos] + g[pos][i].l){ 96 int tmptime = ttime; 97 vis[to] = true; 98 path.push_back(to); 99 ttime += g[pos][i].t; 100 dfs_len(to); 101 path.pop_back(); 102 ttime = tmptime; 103 vis[to] = false; 104 } 105 } 106 107 } 108 109 //void dfs_len(int pos) 110 //{ 111 // if(length > ans_len)return; 112 // if(pos == ed){ 113 // if(length < ans_len || length == ans_len && ttime < time_for_minlen){ 114 // ans_len = length; 115 // time_for_minlen = ttime; 116 // minlen = path; 117 //// if(length == ans_len)len_ununique = true; 118 //// else len_ununique = false; 119 // return; 120 // } 121 // } 122 // for(int i = 0; i < g[pos].size(); i++){ 123 // int to = g[pos][i].v, l = g[pos][i].l, t = g[pos][i].t; 124 // if(!vis[to]){ 125 // vis[to] = true; 126 // int tmplen = length, tmptime = ttime; 127 // length += l; 128 // ttime += t; 129 // path.push_back(to); 130 // dfs_len(to); 131 // length = tmplen; 132 // ttime = tmptime; 133 // path.pop_back(); 134 // vis[to] = false; 135 // } 136 // } 137 //} 138 139 int ans_time = inf, num_for_mintime = inf; 140 int ttt, num; 141 //bool ti_ununique = false; 142 vector<int>mintime; 143 void dfs_time(int pos) 144 { 145 if(pos == ed){ 146 if(num < num_for_mintime){ 147 num_for_mintime = num; 148 mintime = path; 149 return; 150 } 151 } 152 for(int i = 0; i < g[pos].size(); i++){ 153 int to = g[pos][i].v; 154 if(!vis[to] && d_time[to] == d_time[pos] + g[pos][i].t){ 155 vis[to] = true; 156 num++; 157 path.push_back(to); 158 dfs_time(to); 159 num--; 160 vis[to] = false; 161 path.pop_back(); 162 } 163 } 164 } 165 //void dfs_time(int pos) 166 //{ 167 // if(ttt > ans_time)return; 168 // if(pos == ed){ 169 // if(ttt < ans_time || ttt == ans_time && num < num_for_mintime){ 170 // ans_time = ttt; 171 // num_for_mintime = num; 172 // mintime = path; 173 //// if(ttt == ans_time)ti_ununique = true; 174 //// else ti_ununique = false; 175 // return; 176 // } 177 // } 178 // for(int i = 0; i < g[pos].size(); i++){ 179 // int to = g[pos][i].v, t = g[pos][i].t; 180 // if(!vis[to]){ 181 // vis[to] = true; 182 // num++; 183 // int tmptime = ttt; 184 // ttt += t; 185 // path.push_back(to); 186 // dfs_time(to); 187 // num--; 188 // path.pop_back(); 189 // ttt = tmptime; 190 // vis[to] = false; 191 // } 192 // } 193 //} 194 195 int main() 196 { 197 scanf("%d%d", &n, &m); 198 for(int i = 0; i < m; i++){ 199 int u, v; 200 int one_way; 201 int len, ti; 202 scanf("%d%d%d%d%d", &u, &v, &one_way, &len, &ti); 203 g[u].push_back(node(v, len, ti)); 204 if(!one_way){ 205 g[v].push_back(node(u, len, ti)); 206 } 207 } 208 scanf("%d%d", &st, &ed); 209 210 // memset(vis, 0, sizeof(vis)); 211 // vis[st] = true; 212 // dfs_len(st); 213 // memset(vis, 0, sizeof(vis)); 214 // vis[st] = true; 215 // path.clear(); 216 // dfs_time(st); 217 218 dijkstra(); 219 memset(vis, 0, sizeof(vis)); 220 dfs_len(st); 221 memset(vis, 0, sizeof(vis)); 222 path.clear(); 223 dfs_time(st); 224 ans_len = d_len[ed]; 225 ans_time = d_time[ed]; 226 227 if(mintime != minlen){ 228 printf("Distance = %d: %d", ans_len, st); 229 for(int i = 0; i < minlen.size(); i++){ 230 printf(" -> %d", minlen[i]); 231 } 232 printf(" "); 233 printf("Time = %d: %d", ans_time, st); 234 for(int i = 0; i < mintime.size(); i++){ 235 printf(" -> %d", mintime[i]); 236 } 237 printf(" "); 238 } 239 else{ 240 printf("Distance = %d; Time = %d: %d", ans_len, ans_time, st); 241 for(int i = 0; i < minlen.size(); i++){ 242 printf(" -> %d", minlen[i]); 243 } 244 printf(" "); 245 } 246 247 248 return 0; 249 }