#include <iostream> #include <vector> #include <array> #include <algorithm> #include <chrono> #include <unordered_map> #include <tuple> using namespace std; struct tuple_hash { template <class T> inline void hash_combine(std::size_t& seed, const T& val) const { seed ^= std::hash<T>{}(val)+0x9e3779b9 + (seed << 6) + (seed >> 2); } size_t operator()(const tuple<int, int>& t) const { size_t seed = 0; hash_combine(seed, get<0>(t)); hash_combine(seed, get<1>(t)); return seed; } }; struct tuple_hash2 { template <class T> inline void hash_combine(std::size_t& seed, const T& val) const { seed ^= std::hash<T>{}(val)+0x9e3779b9 + (seed << 6) + (seed >> 2); } size_t operator()(const tuple<int, int, long long>& t) const { size_t seed = 0; hash_combine(seed, get<0>(t)); hash_combine(seed, get<1>(t)); hash_combine(seed, get<2>(t)); return seed; } }; unordered_map<tuple<int, int>, long long, tuple_hash> memo; unordered_map<tuple<int, int, long long>, bool, tuple_hash2> memo2; long long calculateSignal(const int n, int routerIn, long long signal, const vector<long long>& routers, const array<array<pair<int, long long>, 200>, 100>& amplifiers, array<bool, 100>& routersUsed ) { if (signal > routers[routerIn - 1]) return -1; if (signal > routers[n - 1]) return -1; //cout << routerIn << "->" << signal << endl; //for (int i = 0; i < n; i++) { // cout << routersUsed[i] << " "; //} //cout << endl; long long newSignal = (routerIn == n) ? signal : -1; for (int w = 1; w <= amplifiers[routerIn - 1][0].first; w++) { int routerOut = amplifiers[routerIn - 1][w].first; long long power = amplifiers[routerIn - 1][w].second; if (signal * power <= routers[routerOut - 1]) { array<bool, 100> ru = routersUsed; if (power > 1) ru.fill(false); else { if (ru[routerIn - 1]) continue; ru[routerIn - 1] = true; } long long s = 0; if (power > 1 && memo.find({ routerOut, signal * power }) != memo.end()) s = memo[{routerOut, signal* power}]; else { s = calculateSignal(n, routerOut, signal * power, routers, amplifiers, ru); if (power > 1) memo[{routerOut, signal* power}] = s; } if (s > newSignal) newSignal = s; } if (newSignal == routers[routerIn - 1]) break; } return newSignal; } int main() { auto start = chrono::steady_clock::now(); array<array<pair<int, long long>, 200>, 100> amplifiers; int t; cin >> t; while (t-- > 0) { array<pair<int, long long>, 200> row; row.fill(make_pair(0, 0LL)); amplifiers.fill(row); memo2.clear(); int n; int m; cin >> n >> m; //cout << "Test " << t << ": " << n << " " << m << endl; vector<long long> routers; for (int i = 0; i < n; i++) { long long a; cin >> a; routers.push_back(a); } for (int i = 0; i < m; i++) { int a; int b; long long w; cin >> a >> b >> w; if (a != b || w > 1) { if (memo2.find({ a,b,w }) == memo2.end()) { memo2[{a, b, w}] = true; amplifiers[a - 1][0].first++; amplifiers[a - 1][amplifiers[a - 1][0].first].first = b; amplifiers[a - 1][amplifiers[a - 1][0].first].second = w; } } } //cout << memo2.size() << endl; array<bool, 100> routersUsed; routersUsed.fill(false); memo.clear(); auto signal = calculateSignal(n, 1, 1, routers, amplifiers, routersUsed); cout << signal << endl; } auto end = chrono::steady_clock::now(); chrono::duration<double> elapsed_seconds = end - start; //cout << "Czas: " << elapsed_seconds.count() << endl; }
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 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | #include <iostream> #include <vector> #include <array> #include <algorithm> #include <chrono> #include <unordered_map> #include <tuple> using namespace std; struct tuple_hash { template <class T> inline void hash_combine(std::size_t& seed, const T& val) const { seed ^= std::hash<T>{}(val)+0x9e3779b9 + (seed << 6) + (seed >> 2); } size_t operator()(const tuple<int, int>& t) const { size_t seed = 0; hash_combine(seed, get<0>(t)); hash_combine(seed, get<1>(t)); return seed; } }; struct tuple_hash2 { template <class T> inline void hash_combine(std::size_t& seed, const T& val) const { seed ^= std::hash<T>{}(val)+0x9e3779b9 + (seed << 6) + (seed >> 2); } size_t operator()(const tuple<int, int, long long>& t) const { size_t seed = 0; hash_combine(seed, get<0>(t)); hash_combine(seed, get<1>(t)); hash_combine(seed, get<2>(t)); return seed; } }; unordered_map<tuple<int, int>, long long, tuple_hash> memo; unordered_map<tuple<int, int, long long>, bool, tuple_hash2> memo2; long long calculateSignal(const int n, int routerIn, long long signal, const vector<long long>& routers, const array<array<pair<int, long long>, 200>, 100>& amplifiers, array<bool, 100>& routersUsed ) { if (signal > routers[routerIn - 1]) return -1; if (signal > routers[n - 1]) return -1; //cout << routerIn << "->" << signal << endl; //for (int i = 0; i < n; i++) { // cout << routersUsed[i] << " "; //} //cout << endl; long long newSignal = (routerIn == n) ? signal : -1; for (int w = 1; w <= amplifiers[routerIn - 1][0].first; w++) { int routerOut = amplifiers[routerIn - 1][w].first; long long power = amplifiers[routerIn - 1][w].second; if (signal * power <= routers[routerOut - 1]) { array<bool, 100> ru = routersUsed; if (power > 1) ru.fill(false); else { if (ru[routerIn - 1]) continue; ru[routerIn - 1] = true; } long long s = 0; if (power > 1 && memo.find({ routerOut, signal * power }) != memo.end()) s = memo[{routerOut, signal* power}]; else { s = calculateSignal(n, routerOut, signal * power, routers, amplifiers, ru); if (power > 1) memo[{routerOut, signal* power}] = s; } if (s > newSignal) newSignal = s; } if (newSignal == routers[routerIn - 1]) break; } return newSignal; } int main() { auto start = chrono::steady_clock::now(); array<array<pair<int, long long>, 200>, 100> amplifiers; int t; cin >> t; while (t-- > 0) { array<pair<int, long long>, 200> row; row.fill(make_pair(0, 0LL)); amplifiers.fill(row); memo2.clear(); int n; int m; cin >> n >> m; //cout << "Test " << t << ": " << n << " " << m << endl; vector<long long> routers; for (int i = 0; i < n; i++) { long long a; cin >> a; routers.push_back(a); } for (int i = 0; i < m; i++) { int a; int b; long long w; cin >> a >> b >> w; if (a != b || w > 1) { if (memo2.find({ a,b,w }) == memo2.end()) { memo2[{a, b, w}] = true; amplifiers[a - 1][0].first++; amplifiers[a - 1][amplifiers[a - 1][0].first].first = b; amplifiers[a - 1][amplifiers[a - 1][0].first].second = w; } } } //cout << memo2.size() << endl; array<bool, 100> routersUsed; routersUsed.fill(false); memo.clear(); auto signal = calculateSignal(n, 1, 1, routers, amplifiers, routersUsed); cout << signal << endl; } auto end = chrono::steady_clock::now(); chrono::duration<double> elapsed_seconds = end - start; //cout << "Czas: " << elapsed_seconds.count() << endl; } |