#include <iostream> #include <vector> #include <set> #include <map> #include <algorithm> template<class T> void wypisz(const T &v, std::ostream &str=std::cerr) { for (auto &i : v) { str << i.first << ":" << i.second << " "; } str << std::endl; } struct Wzmacniacz { int64_t wzmocnienie; int z; int ku; bool operator<(const Wzmacniacz &w) const { if (z != w.z) { return z < w.z; } if (ku != w.ku) { return ku < w.ku; } return wzmocnienie < w.wzmocnienie; } }; int64_t zestaw() { int ruterow; int wzmacniaczy; std::cin >> ruterow >> wzmacniaczy; std::vector<int64_t> przepustowosc; przepustowosc.reserve(ruterow); for (int i = 0; i < ruterow; ++i) { int p; std::cin >> p; przepustowosc.push_back(p); } std::set<Wzmacniacz> rozneWzmacniacze; std::vector<Wzmacniacz> wzmacniacze; std::vector<std::vector<int>> wzmacniaczePrzy(ruterow); wzmacniacze.reserve(wzmacniaczy); for (int i = 0; i < wzmacniaczy; ++i) { int z; int ku; int64_t wzmocnienie; std::cin >> z >> ku >> wzmocnienie; --z; --ku; Wzmacniacz w{wzmocnienie, z, ku}; if (!rozneWzmacniacze.contains(w)){ rozneWzmacniacze.insert(w); wzmacniacze.push_back(w); wzmacniaczePrzy[z].push_back(wzmacniacze.size()-1); } } // Dijkstra w celu /*zbicia rzeczywistej przepustowości*/ sprawdzenia istnienia ścieżki // std::vector<int64_t> maksymalnaPrzepustowoscWyjsciowa(ruterow); std::multimap<int,int> kolejka; kolejka.insert({1, ruterow-1}); // maksymalnaPrzepustowoscWyjsciowa[ruterow-1] = przepustowosc[ruterow] std::map<int, int64_t> minimalneWzmocnienieRazem; minimalneWzmocnienieRazem[ruterow-1] = 1001; for (;!kolejka.empty();) { auto it = kolejka.begin(); int wzmocnienie = it->first; int ku = it->second; kolejka.erase(it); if (minimalneWzmocnienieRazem.contains(ku) && minimalneWzmocnienieRazem[ku] <= wzmocnienie) { continue; } for (const Wzmacniacz &w : wzmacniacze) { if (w.ku == ku && (!minimalneWzmocnienieRazem.contains(w.z) || wzmocnienie * w.wzmocnienie < minimalneWzmocnienieRazem[w.z])) { minimalneWzmocnienieRazem[w.z] = wzmocnienie * w.wzmocnienie; kolejka.insert({minimalneWzmocnienieRazem[w.z], w.z}); } } } // wypisz(minimalneWzmocnienieRazem); if (!minimalneWzmocnienieRazem.contains(1)) { return -1; } // for (int i = 0; i < ruterow; ++i) { // if (minimalneWzmocnienieRazem.contains(i)) { // przepustowosc[i] = std::min(przepustowosc[i], przepustowosc[ruterow-1]/minimalneWzmocnienieRazem[i]); // } // } std::vector<std::set<int64_t>> sygnalyStare(ruterow); std::map<int,std::set<int64_t>> sygnalyBiezace; std::map<int,std::set<int64_t>> sygnalyNowe; sygnalyBiezace[0].insert(1); for (; !sygnalyBiezace.empty() ;) { for (const auto &s: sygnalyBiezace) { for (const int &przy: wzmacniaczePrzy[s.first]) { Wzmacniacz &w = wzmacniacze[przy]; for (const int64_t &sygnal: s.second) { int64_t wzmocniony = sygnal * w.wzmocnienie; if (wzmocniony <= przepustowosc[w.ku] && !sygnalyStare[w.ku].contains(wzmocniony)){ sygnalyNowe[w.ku].insert(wzmocniony); } } } } for (const auto &n : sygnalyNowe) { const std::set<int64_t> &nowePrzy = n.second; int i = n.first; sygnalyStare[i].insert(nowePrzy.begin(), nowePrzy.end()); } sygnalyBiezace.swap(sygnalyNowe); sygnalyNowe.clear(); } if (!sygnalyStare[ruterow-1].empty()) { return *sygnalyStare[ruterow-1].rbegin(); } else { return -1; } } int main() { int zestawow; std::cin >> zestawow; while (zestawow--) { int64_t w = zestaw(); std::cout << w << std::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 | #include <iostream> #include <vector> #include <set> #include <map> #include <algorithm> template<class T> void wypisz(const T &v, std::ostream &str=std::cerr) { for (auto &i : v) { str << i.first << ":" << i.second << " "; } str << std::endl; } struct Wzmacniacz { int64_t wzmocnienie; int z; int ku; bool operator<(const Wzmacniacz &w) const { if (z != w.z) { return z < w.z; } if (ku != w.ku) { return ku < w.ku; } return wzmocnienie < w.wzmocnienie; } }; int64_t zestaw() { int ruterow; int wzmacniaczy; std::cin >> ruterow >> wzmacniaczy; std::vector<int64_t> przepustowosc; przepustowosc.reserve(ruterow); for (int i = 0; i < ruterow; ++i) { int p; std::cin >> p; przepustowosc.push_back(p); } std::set<Wzmacniacz> rozneWzmacniacze; std::vector<Wzmacniacz> wzmacniacze; std::vector<std::vector<int>> wzmacniaczePrzy(ruterow); wzmacniacze.reserve(wzmacniaczy); for (int i = 0; i < wzmacniaczy; ++i) { int z; int ku; int64_t wzmocnienie; std::cin >> z >> ku >> wzmocnienie; --z; --ku; Wzmacniacz w{wzmocnienie, z, ku}; if (!rozneWzmacniacze.contains(w)){ rozneWzmacniacze.insert(w); wzmacniacze.push_back(w); wzmacniaczePrzy[z].push_back(wzmacniacze.size()-1); } } // Dijkstra w celu /*zbicia rzeczywistej przepustowości*/ sprawdzenia istnienia ścieżki // std::vector<int64_t> maksymalnaPrzepustowoscWyjsciowa(ruterow); std::multimap<int,int> kolejka; kolejka.insert({1, ruterow-1}); // maksymalnaPrzepustowoscWyjsciowa[ruterow-1] = przepustowosc[ruterow] std::map<int, int64_t> minimalneWzmocnienieRazem; minimalneWzmocnienieRazem[ruterow-1] = 1001; for (;!kolejka.empty();) { auto it = kolejka.begin(); int wzmocnienie = it->first; int ku = it->second; kolejka.erase(it); if (minimalneWzmocnienieRazem.contains(ku) && minimalneWzmocnienieRazem[ku] <= wzmocnienie) { continue; } for (const Wzmacniacz &w : wzmacniacze) { if (w.ku == ku && (!minimalneWzmocnienieRazem.contains(w.z) || wzmocnienie * w.wzmocnienie < minimalneWzmocnienieRazem[w.z])) { minimalneWzmocnienieRazem[w.z] = wzmocnienie * w.wzmocnienie; kolejka.insert({minimalneWzmocnienieRazem[w.z], w.z}); } } } // wypisz(minimalneWzmocnienieRazem); if (!minimalneWzmocnienieRazem.contains(1)) { return -1; } // for (int i = 0; i < ruterow; ++i) { // if (minimalneWzmocnienieRazem.contains(i)) { // przepustowosc[i] = std::min(przepustowosc[i], przepustowosc[ruterow-1]/minimalneWzmocnienieRazem[i]); // } // } std::vector<std::set<int64_t>> sygnalyStare(ruterow); std::map<int,std::set<int64_t>> sygnalyBiezace; std::map<int,std::set<int64_t>> sygnalyNowe; sygnalyBiezace[0].insert(1); for (; !sygnalyBiezace.empty() ;) { for (const auto &s: sygnalyBiezace) { for (const int &przy: wzmacniaczePrzy[s.first]) { Wzmacniacz &w = wzmacniacze[przy]; for (const int64_t &sygnal: s.second) { int64_t wzmocniony = sygnal * w.wzmocnienie; if (wzmocniony <= przepustowosc[w.ku] && !sygnalyStare[w.ku].contains(wzmocniony)){ sygnalyNowe[w.ku].insert(wzmocniony); } } } } for (const auto &n : sygnalyNowe) { const std::set<int64_t> &nowePrzy = n.second; int i = n.first; sygnalyStare[i].insert(nowePrzy.begin(), nowePrzy.end()); } sygnalyBiezace.swap(sygnalyNowe); sygnalyNowe.clear(); } if (!sygnalyStare[ruterow-1].empty()) { return *sygnalyStare[ruterow-1].rbegin(); } else { return -1; } } int main() { int zestawow; std::cin >> zestawow; while (zestawow--) { int64_t w = zestaw(); std::cout << w << std::endl; } } |