题意与分析
这题也是傻逼题,可是我当时打比赛的时候板子出问题了- -|||,怎么调也调不过。
不过思路是很清晰的:先做n次dijkstra然后重新建图,建完了以后根据新的单向图再跑一次dijkstra。
代码
1 #include <bits/stdc++.h> 2 3 #define ZERO(x) memset(x, 0, sizeof(x)) 4 using namespace std; 5 using ll=long long; 6 7 struct Edge { int v, nxt; ll c; }; 8 Edge w[20005]; 9 vector<int> que; 10 ll dist[1005], a[1005], b[1005]; 11 int e[1005][1005], ww[1005]; 12 bool vis[1005]; 13 int N, M, x, y, W = 1; 14 15 void ShortestPath(int s) 16 { 17 memset(dist, 60, sizeof(dist)); dist[s] = 0; 18 ZERO(vis); vis[s]=true; 19 que.clear(); 20 que.push_back(s); 21 for (int fi = 0; fi < que.size(); ++ fi) 22 { 23 int u = que[fi]; 24 for (int i = ww[u]; i; i = w[i].nxt) 25 { 26 int v = w[i].v; 27 if (dist[v] <= dist[u] + w[i].c) continue; 28 dist[v] = dist[u] + w[i].c; 29 if (vis[v]) continue; 30 vis[v] = true; 31 que.push_back(v); 32 } 33 vis[u] = false; 34 } 35 36 e[s][0] = 0; 37 for (int i = 1; i <= N; ++ i) 38 if (i != s && dist[i] <= a[s]) e[s][++ e[s][0]] = i; 39 } 40 41 42 int main() 43 { 44 cin >> N >> M; 45 cin >> x >> y; 46 for (int i = 1, u, v; i <= M; ++ i) 47 { 48 ll c; 49 cin >> u >> v >> c; 50 w[++ W].v = v; w[W].c = c; w[W].nxt = ww[u]; ww[u] = W; 51 w[++ W].v = u; w[W].c = c; w[W].nxt = ww[v]; ww[v] = W; 52 } 53 for (int i = 1; i <= N; ++ i) cin >> a[i] >> b[i]; 54 for (int i = 1; i <= N; ++ i) ShortestPath(i); 55 56 memset(dist, 60, sizeof(dist)); dist[x] = 0; 57 ZERO(vis); vis[x]=true; 58 que.clear(); 59 que.push_back(x); 60 for (int fi = 0; fi < que.size(); ++ fi) 61 { 62 int u = que[fi]; 63 for (int i = 1; i <= e[u][0]; ++ i) 64 { 65 int v = e[u][i]; 66 if (dist[v] <= dist[u] + b[u]) continue; 67 dist[v] = dist[u] + b[u]; 68 if (vis[v]) continue; 69 vis[v] = 1; 70 que.push_back(v); 71 } 72 vis[u] = 0; 73 } 74 75 if (dist[y] > (1ll << 60)) dist[y] = -1; 76 cout << dist[y] << endl; 77 78 return 0; 79 }点我看时雨色图