/* 2024 * Maciej Szeptuch */ #include <cstdio> #include <queue> #include <tuple> #include <vector> const int MAX_VERTS = 200001; int verts; int edges; int queries; int color[MAX_VERTS]; std::vector<std::pair<int, int>> graph[MAX_VERTS]; void color_verts(int start, long long int max_cost, int new_color); int main(void) { scanf("%d %d %d\n", &verts, &edges, &queries); for(int e = 0; e < edges; ++e) { int v1; int v2; int cost; scanf("%d %d %d", &v1, &v2, &cost); --v1; --v2; graph[v1].push_back({v2, cost}); graph[v2].push_back({v1, cost}); } for(int q = 0; q < queries; ++q) { int operation; int new_color; long long int max_cost; int v1; int v2; int cost; scanf("%d", &operation); switch(operation) { case 1: scanf("%d %d %d", &v1, &v2, &cost); --v1; --v2; graph[v1].push_back({v2, cost}); graph[v2].push_back({v1, cost}); break; case 2: scanf("%d %d", &v1, &v2); --v1; --v2; for(size_t n = 0; n < graph[v1].size(); ++n) if(graph[v1][n].first == v2) { graph[v1][n] = graph[v1].back(); graph[v1].pop_back(); break; } for(size_t n = 0; n < graph[v2].size(); ++n) if(graph[v2][n].first == v1) { graph[v2][n] = graph[v2].back(); graph[v2].pop_back(); break; } break; case 3: scanf("%d %lld %d", &v1, &max_cost, &new_color); --v1; color_verts(v1, max_cost, new_color); break; case 4: scanf("%d", &v1); printf("%d\n", color[v1 - 1]); break; } } return 0; } inline void color_verts(int start, long long int max_cost, int new_color) { std::queue<std::tuple<int, long long int, int>> que; que.push({start, 0llu, -1}); while(!que.empty()) { auto [v, current_cost, parent] = que.front(); que.pop(); color[v] = new_color; for(auto &[n, edge_cost]: graph[v]) { if(n == parent) continue; if(current_cost + edge_cost > max_cost) continue; que.push({n, current_cost + edge_cost, v}); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | /* 2024 * Maciej Szeptuch */ #include <cstdio> #include <queue> #include <tuple> #include <vector> const int MAX_VERTS = 200001; int verts; int edges; int queries; int color[MAX_VERTS]; std::vector<std::pair<int, int>> graph[MAX_VERTS]; void color_verts(int start, long long int max_cost, int new_color); int main(void) { scanf("%d %d %d\n", &verts, &edges, &queries); for(int e = 0; e < edges; ++e) { int v1; int v2; int cost; scanf("%d %d %d", &v1, &v2, &cost); --v1; --v2; graph[v1].push_back({v2, cost}); graph[v2].push_back({v1, cost}); } for(int q = 0; q < queries; ++q) { int operation; int new_color; long long int max_cost; int v1; int v2; int cost; scanf("%d", &operation); switch(operation) { case 1: scanf("%d %d %d", &v1, &v2, &cost); --v1; --v2; graph[v1].push_back({v2, cost}); graph[v2].push_back({v1, cost}); break; case 2: scanf("%d %d", &v1, &v2); --v1; --v2; for(size_t n = 0; n < graph[v1].size(); ++n) if(graph[v1][n].first == v2) { graph[v1][n] = graph[v1].back(); graph[v1].pop_back(); break; } for(size_t n = 0; n < graph[v2].size(); ++n) if(graph[v2][n].first == v1) { graph[v2][n] = graph[v2].back(); graph[v2].pop_back(); break; } break; case 3: scanf("%d %lld %d", &v1, &max_cost, &new_color); --v1; color_verts(v1, max_cost, new_color); break; case 4: scanf("%d", &v1); printf("%d\n", color[v1 - 1]); break; } } return 0; } inline void color_verts(int start, long long int max_cost, int new_color) { std::queue<std::tuple<int, long long int, int>> que; que.push({start, 0llu, -1}); while(!que.empty()) { auto [v, current_cost, parent] = que.front(); que.pop(); color[v] = new_color; for(auto &[n, edge_cost]: graph[v]) { if(n == parent) continue; if(current_cost + edge_cost > max_cost) continue; que.push({n, current_cost + edge_cost, v}); } } } |