From dd80e1ea1ee4c5384e0cf47fdd843ddcec2f1256 Mon Sep 17 00:00:00 2001 From: Minseong Gwak Date: Sun, 2 Nov 2025 17:15:27 +0900 Subject: [PATCH] update dijk & bsb --- .gitignore | 2 +- Makefile | 16 ++--- compile_commands.json | 18 ----- include/testlib.h | 155 +++++++++++++++++++++++++----------------- src/bsb/main.cpp | 144 +++++++++++++++++++++++++++++++++------ src/dijk/main.cpp | 20 ++++-- src/dijk2/main.cpp | 51 ++++++++++++++ 7 files changed, 289 insertions(+), 117 deletions(-) delete mode 100644 compile_commands.json create mode 100644 src/dijk2/main.cpp diff --git a/.gitignore b/.gitignore index b89e5e0..65bb6e0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ build/ .cache -.compile_commands.json +compile_commands.json .DS_Store \ No newline at end of file diff --git a/Makefile b/Makefile index 8e43657..ec53412 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ BUILD_OUT_B_DIR = $(BUILD_DIR)/$(SOL_B)_out DIRS = $(BUILD_DIR) $(BUILD_TARGET_DIR) $(BUILD_GEN_DIR) $(BUILD_VAL_DIR) $(BUILD_CHK_DIR) $(LOG_DIR) $(BUILD_IN_DIR) $(BUILD_OUT_A_DIR) $(BUILD_OUT_B_DIR) -CXXFLAGS = -Wall -O2 -std=c++2a -I$(INC_DIR) +CXXFLAGS = -Wall -O2 -std=c++2a GENFLAGS = -N $(N) -M $(M) -pm $(pm) SRC_MAIN_FILES = $(wildcard $(SRC_DIR)/*/main.cpp) @@ -65,15 +65,15 @@ $(BUILD_TARGET_DIR)/%: $(SRC_DIR)/%/main.cpp | $(BUILD_TARGET_DIR) $(BUILD_GEN_DIR)/%: $(GEN_DIR)/%.cpp | $(BUILD_GEN_DIR) @echo "Compiling Generator $< -> $@" - $(CXX) $(CXXFLAGS) -o $@ $< + $(CXX) $(CXXFLAGS) -I$(INC_DIR) -o $@ $< $(BUILD_VAL_DIR)/%: $(VAL_DIR)/%.cpp | $(BUILD_VAL_DIR) @echo "Compiling Validator $< -> $@" - $(CXX) $(CXXFLAGS) -o $@ $< + $(CXX) $(CXXFLAGS) -I$(INC_DIR) -o $@ $< $(BUILD_CHK_DIR)/%: $(CHK_DIR)/%.cpp | $(BUILD_CHK_DIR) @echo "Compiling Checker $< -> $@" - $(CXX) $(CXXFLAGS) -o $@ $< + $(CXX) $(CXXFLAGS) -I$(INC_DIR) -o $@ $< .PRECIOUS: $(BUILD_IN_DIR)/input% $(BUILD_IN_DIR)/input%: $(GEN_TO_RUN) | $(BUILD_IN_DIR) @@ -148,6 +148,7 @@ else @echo "OK: ID=$(id) outputs match!" endif + .PHONY: test test: all $(LOG_DIR) $(BUILD_OUT_A_DIR) $(BUILD_OUT_B_DIR) ifeq ($(id),) @@ -155,7 +156,7 @@ ifeq ($(id),) @echo "--- Using Generator [$(gen)] (N=$(N), M=$(M)) ---" @LOG_FILE=$(LOG_DIR)/test_run_$$(date +%Y%m%d_%H%M%S).log; \ echo "--- Logging to $${LOG_FILE} ---"; \ - script -q /dev/null /bin/bash -c ' \ + script -q -c ' \ set -o pipefail; \ for i in {1..$(TEST_COUNT)}; do \ IN_FILE_LOOP=$(BUILD_IN_DIR)/input$$(printf "%05d" $$i); \ @@ -179,7 +180,7 @@ ifeq ($(id),) ( ./$(CHK_EXE) $$IN_FILE_LOOP $$OUT_A_FILE_LOOP $$OUT_B_FILE_LOOP ) 2>&1 || { printf "\nWA! (Input: $$IN_FILE_LOOP)\n"; echo "Input saved to $$IN_FILE_LOOP"; exit 1; }; \ done; \ echo "--- All $(TEST_COUNT) tests passed! ---"; \ - ' | tee $${LOG_FILE}; \ + ' /dev/null | tee $${LOG_FILE}; \ if [ $${PIPESTATUS[0]} -ne 0 ]; then \ printf "\n--- TESTS FAILED! See %s ---\n" "$${LOG_FILE}"; \ exit 1; \ @@ -189,9 +190,6 @@ else @$(MAKE) --no-print-directory check id=$(id) gen=$(gen) SOL_A=$(SOL_A) SOL_B=$(SOL_B) N=$(N) M=$(M) endif - - - .PHONY: bench bench: all ifeq ($(id),) diff --git a/compile_commands.json b/compile_commands.json deleted file mode 100644 index 5bc1667..0000000 --- a/compile_commands.json +++ /dev/null @@ -1,18 +0,0 @@ -[ - { - "arguments": [ - "/Users/manager/.local/bin/g++", - "-c", - "-Wall", - "-O2", - "-std=c++2a", - "-Iinclude", - "-o", - "build/val/validator", - "validator/validator.cpp" - ], - "directory": "/Users/manager/Documents/Research/Algorithm/BSB", - "file": "/Users/manager/Documents/Research/Algorithm/BSB/validator/validator.cpp", - "output": "/Users/manager/Documents/Research/Algorithm/BSB/build/val/validator" - } -] diff --git a/include/testlib.h b/include/testlib.h index 3ac3a1d..7817d0d 100644 --- a/include/testlib.h +++ b/include/testlib.h @@ -405,7 +405,8 @@ template #ifdef __GNUC__ __attribute__((const)) #endif -static inline T __testlib_abs(const T &x) { +static inline T +__testlib_abs(const T &x) { return x > 0 ? x : -x; } @@ -413,7 +414,8 @@ template #ifdef __GNUC__ __attribute__((const)) #endif -static inline T __testlib_min(const T &a, const T &b) { +static inline T +__testlib_min(const T &a, const T &b) { return a < b ? a : b; } @@ -421,7 +423,8 @@ template #ifdef __GNUC__ __attribute__((const)) #endif -static inline T __testlib_max(const T &a, const T &b) { +static inline T +__testlib_max(const T &a, const T &b) { return a > b ? a : b; } @@ -429,14 +432,16 @@ template #ifdef __GNUC__ __attribute__((const)) #endif -static inline T __testlib_crop(T value, T a, T b) { +static inline T +__testlib_crop(T value, T a, T b) { return __testlib_min(__testlib_max(value, a), --b); } #ifdef __GNUC__ __attribute__((const)) #endif -static inline double __testlib_crop(double value, double a, double b) { +static inline double +__testlib_crop(double value, double a, double b) { value = __testlib_min(__testlib_max(value, a), b); if (value >= b) value = std::nexttoward(b, a); return value; @@ -455,7 +460,8 @@ static bool __testlib_prelimIsNaN(double r) { #ifdef __GNUC__ __attribute__((const)) #endif -static std::string removeDoubleTrailingZeroes(std::string value) { +static std::string +removeDoubleTrailingZeroes(std::string value) { while (!value.empty() && value[value.length() - 1] == '0' && value.find('.') != std::string::npos) value = value.substr(0, value.length() - 1); @@ -468,7 +474,8 @@ static std::string removeDoubleTrailingZeroes(std::string value) { #ifdef __GNUC__ __attribute__((const)) #endif -inline std::string upperCase(std::string s) { +inline std::string +upperCase(std::string s) { for (size_t i = 0; i < s.length(); i++) if ('a' <= s[i] && s[i] <= 'z') s[i] = char(s[i] - 'a' + 'A'); return s; @@ -477,7 +484,8 @@ inline std::string upperCase(std::string s) { #ifdef __GNUC__ __attribute__((const)) #endif -inline std::string lowerCase(std::string s) { +inline std::string +lowerCase(std::string s) { for (size_t i = 0; i < s.length(); i++) if ('A' <= s[i] && s[i] <= 'Z') s[i] = char(s[i] - 'A' + 'a'); return s; @@ -486,7 +494,8 @@ inline std::string lowerCase(std::string s) { #ifdef __GNUC__ __attribute__((format(printf, 1, 2))) #endif -std::string format(const char *fmt, ...) { +std::string +format(const char *fmt, ...) { FMT_TO_RESULT(fmt, fmt, result); return result; } @@ -499,7 +508,8 @@ std::string format(const std::string fmt, ...) { #ifdef __GNUC__ __attribute__((const)) #endif -static std::string __testlib_part(const std::string &s); +static std::string +__testlib_part(const std::string &s); static bool __testlib_isNaN(double r) { __TESTLIB_STATIC_ASSERT(sizeof(double) == sizeof(long long)); @@ -532,8 +542,8 @@ static bool __testlib_isInfinite(double r) { #ifdef __GNUC__ __attribute__((const)) #endif -inline bool doubleCompare(double expected, double result, - double MAX_DOUBLE_ERROR) { +inline bool +doubleCompare(double expected, double result, double MAX_DOUBLE_ERROR) { MAX_DOUBLE_ERROR += 1E-15; if (__testlib_isNaN(expected)) { return __testlib_isNaN(result); @@ -559,7 +569,8 @@ inline bool doubleCompare(double expected, double result, #ifdef __GNUC__ __attribute__((const)) #endif -inline double doubleDelta(double expected, double result) { +inline double +doubleDelta(double expected, double result) { double absolute = __testlib_abs(result - expected); if (__testlib_abs(expected) > 1E-9) { @@ -621,7 +632,8 @@ template #ifdef __GNUC__ __attribute__((const)) #endif -static std::string vtos(const T &t, std::true_type) { +static std::string +vtos(const T &t, std::true_type) { if (t == 0) return "0"; else { @@ -1014,7 +1026,8 @@ class random_t { #ifdef __GNUC__ __attribute__((format(printf, 2, 3))) #endif - std::string next(const char *format, ...) { + std::string + next(const char *format, ...) { FMT_TO_RESULT(format, format, ptrn); return next(ptrn); } @@ -1385,8 +1398,8 @@ static bool __pattern_isSlash(const std::string &s, size_t pos) { #ifdef __GNUC__ __attribute__((pure)) #endif -static bool __pattern_isCommandChar(const std::string &s, size_t pos, - char value) { +static bool +__pattern_isCommandChar(const std::string &s, size_t pos, char value) { if (pos >= s.length()) return false; int slashes = 0; @@ -1409,8 +1422,9 @@ static char __pattern_getChar(const std::string &s, size_t &pos) { #ifdef __GNUC__ __attribute__((pure)) #endif -static int __pattern_greedyMatch(const std::string &s, size_t pos, - const std::vector chars) { +static int +__pattern_greedyMatch(const std::string &s, size_t pos, + const std::vector chars) { int result = 0; while (pos < s.length()) { @@ -2446,7 +2460,8 @@ struct InStream { #ifdef __GNUC__ __attribute__((format(printf, 3, 4))) #endif - void ensuref(bool cond, const char *format, ...); + void + ensuref(bool cond, const char *format, ...); void __testlib_ensure(bool cond, std::string message); @@ -2496,7 +2511,7 @@ struct ValidatorBoundsHit { bool maxHit; ValidatorBoundsHit(bool minHit = false, bool maxHit = false) - : minHit(minHit), maxHit(maxHit) {}; + : minHit(minHit), maxHit(maxHit){}; ValidatorBoundsHit merge(const ValidatorBoundsHit &validatorBoundsHit, bool ignoreMinBound, bool ignoreMaxBound) { @@ -3227,7 +3242,8 @@ NORETURN void InStream::quit(TResult result, const char *msg) { #ifdef __GNUC__ __attribute__((format(printf, 3, 4))) #endif -NORETURN void InStream::quitf(TResult result, const char *msg, ...) { +NORETURN void +InStream::quitf(TResult result, const char *msg, ...) { FMT_TO_RESULT(msg, msg, message); InStream::quit(result, message.c_str()); } @@ -3443,7 +3459,8 @@ void InStream::readTokenTo(std::string &result) { readWordTo(result); } #ifdef __GNUC__ __attribute__((const)) #endif -static std::string __testlib_part(const std::string &s) { +static std::string +__testlib_part(const std::string &s) { std::string t; for (size_t i = 0; i < s.length(); i++) if (s[i] != '\0') @@ -3595,7 +3612,8 @@ void InStream::readTokenTo(std::string &result, const std::string &ptrn, #ifdef __GNUC__ __attribute__((pure)) #endif -static inline bool equals(long long integer, const char *s) { +static inline bool +equals(long long integer, const char *s) { if (integer == LLONG_MIN) return strcmp(s, "-9223372036854775808") == 0; if (integer == 0LL) return strcmp(s, "0") == 0; @@ -3625,7 +3643,8 @@ static inline bool equals(long long integer, const char *s) { #ifdef __GNUC__ __attribute__((pure)) #endif -static inline bool equals(unsigned long long integer, const char *s) { +static inline bool +equals(unsigned long long integer, const char *s) { if (integer == ULLONG_MAX) return strcmp(s, "18446744073709551615") == 0; if (integer == 0ULL) return strcmp(s, "0") == 0; @@ -4607,7 +4626,8 @@ template #ifdef __GNUC__ __attribute__((format(printf, 2, 3))) #endif -NORETURN void quitp(F points, const char *format, ...) { +NORETURN void +quitp(F points, const char *format, ...) { FMT_TO_RESULT(format, format, message); quitp(points, message); } @@ -4615,7 +4635,8 @@ NORETURN void quitp(F points, const char *format, ...) { #ifdef __GNUC__ __attribute__((format(printf, 2, 3))) #endif -NORETURN void quitf(TResult result, const char *format, ...) { +NORETURN void +quitf(TResult result, const char *format, ...) { FMT_TO_RESULT(format, format, message); quit(result, message); } @@ -5159,7 +5180,8 @@ static inline void __testlib_ensure(bool cond, const std::string &msg) { #ifdef __GNUC__ __attribute__((unused)) #endif -static inline void __testlib_ensure(bool cond, const char *msg) { +static inline void +__testlib_ensure(bool cond, const char *msg) { if (!cond) quit(_fail, msg); } @@ -5173,7 +5195,8 @@ static inline void __testlib_ensure(bool cond, const char *msg) { #ifdef __GNUC__ __attribute__((format(printf, 2, 3))) #endif -inline void ensuref(bool cond, const char *format, ...) { +inline void +ensuref(bool cond, const char *format, ...) { if (!cond) { FMT_TO_RESULT(format, format, message); __testlib_ensure(cond, message); @@ -5264,14 +5287,16 @@ void startTest(int test) { #ifdef __GNUC__ __attribute__((const)) #endif -inline std::string compress(const std::string &s) { +inline std::string +compress(const std::string &s) { return __testlib_part(s); } #ifdef __GNUC__ __attribute__((const)) #endif -inline std::string englishEnding(int x) { +inline std::string +englishEnding(int x) { x %= 100; if (x / 10 == 1) return "th"; if (x % 10 == 1) return "st"; @@ -5284,8 +5309,8 @@ template #ifdef __GNUC__ __attribute__((const)) #endif -std::string join(_ForwardIterator first, _ForwardIterator last, - _Separator separator) { +std::string +join(_ForwardIterator first, _ForwardIterator last, _Separator separator) { std::stringstream ss; bool repeated = false; for (_ForwardIterator i = first; i != last; i++) { @@ -5302,7 +5327,8 @@ template #ifdef __GNUC__ __attribute__((const)) #endif -std::string join(_ForwardIterator first, _ForwardIterator last) { +std::string +join(_ForwardIterator first, _ForwardIterator last) { return join(first, last, ' '); } @@ -5310,7 +5336,8 @@ template #ifdef __GNUC__ __attribute__((const)) #endif -std::string join(const _Collection &collection, _Separator separator) { +std::string +join(const _Collection &collection, _Separator separator) { return join(collection.begin(), collection.end(), separator); } @@ -5318,7 +5345,8 @@ template #ifdef __GNUC__ __attribute__((const)) #endif -std::string join(const _Collection &collection) { +std::string +join(const _Collection &collection) { return join(collection, ' '); } @@ -5329,7 +5357,8 @@ std::string join(const _Collection &collection) { #ifdef __GNUC__ __attribute__((const)) #endif -std::vector split(const std::string &s, char separator) { +std::vector +split(const std::string &s, char separator) { std::vector result; std::string item; for (size_t i = 0; i < s.length(); i++) @@ -5349,8 +5378,8 @@ std::vector split(const std::string &s, char separator) { #ifdef __GNUC__ __attribute__((const)) #endif -std::vector split(const std::string &s, - const std::string &separators) { +std::vector +split(const std::string &s, const std::string &separators) { if (separators.empty()) return std::vector(1, s); std::vector isSeparator(256); @@ -5375,7 +5404,8 @@ std::vector split(const std::string &s, #ifdef __GNUC__ __attribute__((const)) #endif -std::vector tokenize(const std::string &s, char separator) { +std::vector +tokenize(const std::string &s, char separator) { std::vector result; std::string item; for (size_t i = 0; i < s.length(); i++) @@ -5394,8 +5424,8 @@ std::vector tokenize(const std::string &s, char separator) { #ifdef __GNUC__ __attribute__((const)) #endif -std::vector tokenize(const std::string &s, - const std::string &separators) { +std::vector +tokenize(const std::string &s, const std::string &separators) { if (separators.empty()) return std::vector(1, s); std::vector isSeparator(256); @@ -5443,8 +5473,9 @@ template #ifdef __GNUC__ __attribute__((format(printf, 4, 5))) #endif -NORETURN void expectedButFound(TResult result, T expected, T found, - const char *prependFormat = "", ...) { +NORETURN void +expectedButFound(TResult result, T expected, T found, + const char *prependFormat = "", ...) { FMT_TO_RESULT(prependFormat, prependFormat, prepend); std::string expectedString = vtos(expected); std::string foundString = vtos(found); @@ -5456,10 +5487,10 @@ template <> #ifdef __GNUC__ __attribute__((format(printf, 4, 5))) #endif -NORETURN void expectedButFound(TResult result, - std::string expected, - std::string found, - const char *prependFormat, ...) { +NORETURN void +expectedButFound(TResult result, std::string expected, + std::string found, const char *prependFormat, + ...) { FMT_TO_RESULT(prependFormat, prependFormat, prepend); __testlib_expectedButFound(result, expected, found, prepend.c_str()); } @@ -5468,9 +5499,9 @@ template <> #ifdef __GNUC__ __attribute__((format(printf, 4, 5))) #endif -NORETURN void expectedButFound(TResult result, double expected, - double found, const char *prependFormat, - ...) { +NORETURN void +expectedButFound(TResult result, double expected, double found, + const char *prependFormat, ...) { FMT_TO_RESULT(prependFormat, prependFormat, prepend); std::string expectedString = removeDoubleTrailingZeroes(format("%.12f", expected)); @@ -5484,10 +5515,10 @@ template <> #ifdef __GNUC__ __attribute__((format(printf, 4, 5))) #endif -NORETURN void expectedButFound(TResult result, - const char *expected, - const char *found, - const char *prependFormat, ...) { +NORETURN void +expectedButFound(TResult result, const char *expected, + const char *found, const char *prependFormat, + ...) { FMT_TO_RESULT(prependFormat, prependFormat, prepend); __testlib_expectedButFound(result, std::string(expected), std::string(found), prepend.c_str()); @@ -5497,9 +5528,9 @@ template <> #ifdef __GNUC__ __attribute__((format(printf, 4, 5))) #endif -NORETURN void expectedButFound(TResult result, float expected, - float found, const char *prependFormat, - ...) { +NORETURN void +expectedButFound(TResult result, float expected, float found, + const char *prependFormat, ...) { FMT_TO_RESULT(prependFormat, prependFormat, prepend); __testlib_expectedButFound(result, double(expected), double(found), prepend.c_str()); @@ -5509,10 +5540,10 @@ template <> #ifdef __GNUC__ __attribute__((format(printf, 4, 5))) #endif -NORETURN void expectedButFound(TResult result, - long double expected, - long double found, - const char *prependFormat, ...) { +NORETURN void +expectedButFound(TResult result, long double expected, + long double found, const char *prependFormat, + ...) { FMT_TO_RESULT(prependFormat, prependFormat, prepend); __testlib_expectedButFound(result, double(expected), double(found), prepend.c_str()); diff --git a/src/bsb/main.cpp b/src/bsb/main.cpp index 07e174f..bd6e117 100644 --- a/src/bsb/main.cpp +++ b/src/bsb/main.cpp @@ -1,51 +1,153 @@ +#include #include #include #include -#include #include #include +#include +#include +#include +#include + +#include + using namespace std; + using ll = long long; +using Edge = tuple; +using ADJ_LIST = vector > >; + +using Item = pair; +using Fiboheap = boost::heap::fibonacci_heap > >; const double INF = numeric_limits::infinity(); +pair, vector > FindPivots(double B, vector S, const ADJ_LIST& adj, vector& dist, ll k, ll t) +{ + unordered_set U; + for(auto i: S) U.insert(i); + + unordered_set bef = U; + for(ll tr = 1; tr <= k; tr++) + { + unordered_set st; + for(auto s:bef) + { + for(auto [i, len] : adj[s]) + { + if(dist[i] >= dist[s] + len) + { + + } + } + } + + for(auto i:st) U.insert(i); + swap(st, bef); + } +} + +pair > BMSSP(ll l, vector S, double B, const ADJ_LIST& adj, vector& dist, ll k, ll t) +{ + assert(S.size() <= 1LL<<(l*t)); + + if(l == 0) + { + ll s = S.front(); + + vector U; + Fiboheap pq; unordered_map > handle; + + handle[s] = pq.push({dist[s], s}); + + while(!pq.empty() && U.size() < k+1) + { + auto [du, u] = pq.top(); pq.pop(); + handle[u] = nullopt; + + U.push_back(u); + + for(auto [v, len] : adj[u]) + { + if(dist[u]+len >= dist[v] && dist[u]+len < B && (!handle.count(v) || handle[v] != nullopt)) + { + dist[v] = dist[u] + len; + if(handle.count(v)) pq.increase(handle[v].value(), {dist[v], v}); + else handle[v] = pq.push({dist[v], v}); + } + } + } + + if(U.size() <= k) return {B, U}; + double B_ = dist[U.front()]; + for(auto i:U) B_ = max(B_, dist[i]); + + return {B_, U}; + } + + double B_ = B; + vector U = S; + + auto [P, W] = FindPivots(B, S, adj, dist, k, t); + + return {B_, U}; +} int main() { - std::ios::sync_with_stdio(false); + ios::sync_with_stdio(false); ll n, m; cin >> n >> m; - vector > > adj(n + 1); + vector edges; for (ll i = 1; i <= m; i++) { ll s, e; double len; cin >> s >> e >> len; - adj[s].emplace_back(e, len); + edges.emplace_back(s, e, len); } - vector dist(n + 1, INF); + vector > renum(n + 1); + ll c = 0; - using Item = pair; - priority_queue, greater > pq; - vector chk(n + 1); + auto get = [&c, &renum](ll x) -> ll { + renum[x].push_back(++c); + return c; + }; - dist[1] = 0; - pq.push({dist[1], 1}); - while (!pq.empty()) { - auto [_, s] = pq.top(); - pq.pop(); - if (chk[s]) continue; - chk[s] = true; - for (auto [i, len] : adj[s]) { - if (dist[i] > dist[s] + len) { - dist[i] = dist[s] + len; - pq.push({dist[i], i}); - } + ADJ_LIST adj(2*m + 1); + + for (auto [s, e, len] : edges) { + adj[get(s)].emplace_back(get(e), len); + } + + assert(c == 2*m); + + for (ll i = 1; i <= n; i++) { + if (renum[i].size() <= 1) continue; + + ll k = renum[i].size(); + for (ll s = 0; s < k; s++) { + adj[renum[i][s]].emplace_back(renum[i][(s+1)%k], 0.0); } } + + const ll k = floor(pow(log2(2*m), 1.0/3)); + const ll t = floor(pow(log2(2*m), 2.0/3)); + + const ll l = ceil((log2(2*m)/t)); + + const int s = 1; + vector dist(2*m+1, INF); + dist[s] = 1; + + auto [B_, U] = BMSSP(l, {s}, INF, adj, dist, k, t); + + vector ans(n+1, INF); + for(ll i=1;i<=n;i++) if(!renum[i].empty()) ans[i] = dist[renum[i].front()]; + cout << fixed << setprecision(15); - for (ll i = 1; i <= n; i++) cout << dist[i] << '\n'; + for (ll i = 1; i <= n; i++) cout << ans[i] << '\n'; } \ No newline at end of file diff --git a/src/dijk/main.cpp b/src/dijk/main.cpp index affc47c..0c32614 100644 --- a/src/dijk/main.cpp +++ b/src/dijk/main.cpp @@ -1,12 +1,16 @@ +#include +#include #include #include -#include #include #include using namespace std; using ll = long long; +using Item = pair; +using Fiboheap = boost::heap::fibonacci_heap > >; + const double INF = numeric_limits::infinity(); int main() { @@ -27,24 +31,28 @@ int main() { vector dist(n + 1, INF); - using Item = pair; - priority_queue, greater > pq; + Fiboheap pq; vector chk(n + 1); - + vector handles(n + 1); dist[1] = 0; pq.push({dist[1], 1}); + for (ll i = 1; i <= n; i++) handles[i] = pq.push({dist[i], i}); + while (!pq.empty()) { auto [_, s] = pq.top(); pq.pop(); + if (chk[s]) continue; chk[s] = true; + for (auto [i, len] : adj[s]) { - if (dist[i] > dist[s] + len) { + if (!chk[i] && dist[i] > dist[s] + len) { dist[i] = dist[s] + len; - pq.push({dist[i], i}); + pq.increase(handles[i], {dist[i], i}); } } } + cout << fixed << setprecision(15); for (ll i = 1; i <= n; i++) cout << dist[i] << '\n'; } \ No newline at end of file diff --git a/src/dijk2/main.cpp b/src/dijk2/main.cpp new file mode 100644 index 0000000..a4f398d --- /dev/null +++ b/src/dijk2/main.cpp @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +#include + +using namespace std; +using ll = long long; + +const double INF = numeric_limits::infinity(); + +int main() { + std::ios::sync_with_stdio(false); + + ll n, m; + cin >> n >> m; + + vector > > adj(n + 1); + + for (ll i = 1; i <= m; i++) { + ll s, e; + double len; + cin >> s >> e >> len; + + adj[s].emplace_back(e, len); + } + + vector dist(n + 1, INF); + + using Item = pair; + priority_queue, greater > pq; + vector chk(n + 1); + + dist[1] = 0; + pq.push({dist[1], 1}); + while (!pq.empty()) { + auto [_, s] = pq.top(); + pq.pop(); + if (chk[s]) continue; + chk[s] = true; + for (auto [i, len] : adj[s]) { + if (!chk[i] && dist[i] > dist[s] + len) { + dist[i] = dist[s] + len; + pq.push({dist[i], i}); + } + } + } + cout << fixed << setprecision(15); + for (ll i = 1; i <= n; i++) cout << dist[i] << '\n'; +} \ No newline at end of file