update dijk & bsb

This commit is contained in:
2025-11-02 17:15:27 +09:00
parent 7644286515
commit dd80e1ea1e
7 changed files with 289 additions and 117 deletions

2
.gitignore vendored
View File

@@ -1,5 +1,5 @@
build/
.cache
.compile_commands.json
compile_commands.json
.DS_Store

View File

@@ -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),)

View File

@@ -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"
}
]

View File

@@ -405,7 +405,8 @@ template <typename T>
#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 <typename T>
#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 <typename T>
#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 <typename T>
#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 <typename T>
#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<char> chars) {
static int
__pattern_greedyMatch(const std::string &s, size_t pos,
const std::vector<char> 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 <typename F>
#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 <typename _ForwardIterator, typename _Separator>
#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 <typename _ForwardIterator>
#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 <typename _Collection, typename _Separator>
#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 <typename _Collection>
#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<std::string> split(const std::string &s, char separator) {
std::vector<std::string>
split(const std::string &s, char separator) {
std::vector<std::string> result;
std::string item;
for (size_t i = 0; i < s.length(); i++)
@@ -5349,8 +5378,8 @@ std::vector<std::string> split(const std::string &s, char separator) {
#ifdef __GNUC__
__attribute__((const))
#endif
std::vector<std::string> split(const std::string &s,
const std::string &separators) {
std::vector<std::string>
split(const std::string &s, const std::string &separators) {
if (separators.empty()) return std::vector<std::string>(1, s);
std::vector<bool> isSeparator(256);
@@ -5375,7 +5404,8 @@ std::vector<std::string> split(const std::string &s,
#ifdef __GNUC__
__attribute__((const))
#endif
std::vector<std::string> tokenize(const std::string &s, char separator) {
std::vector<std::string>
tokenize(const std::string &s, char separator) {
std::vector<std::string> result;
std::string item;
for (size_t i = 0; i < s.length(); i++)
@@ -5394,8 +5424,8 @@ std::vector<std::string> tokenize(const std::string &s, char separator) {
#ifdef __GNUC__
__attribute__((const))
#endif
std::vector<std::string> tokenize(const std::string &s,
const std::string &separators) {
std::vector<std::string>
tokenize(const std::string &s, const std::string &separators) {
if (separators.empty()) return std::vector<std::string>(1, s);
std::vector<bool> isSeparator(256);
@@ -5443,8 +5473,9 @@ template <typename T>
#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<std::string>(TResult result,
std::string expected,
std::string found,
const char *prependFormat, ...) {
NORETURN void
expectedButFound<std::string>(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<double>(TResult result, double expected,
double found, const char *prependFormat,
...) {
NORETURN void
expectedButFound<double>(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<const char *>(TResult result,
const char *expected,
const char *found,
const char *prependFormat, ...) {
NORETURN void
expectedButFound<const char *>(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<float>(TResult result, float expected,
float found, const char *prependFormat,
...) {
NORETURN void
expectedButFound<float>(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<long double>(TResult result,
long double expected,
long double found,
const char *prependFormat, ...) {
NORETURN void
expectedButFound<long double>(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());

View File

@@ -1,51 +1,153 @@
#include <cassert>
#include <iomanip>
#include <iostream>
#include <limits>
#include <queue>
#include <utility>
#include <vector>
#include <cmath>
#include <optional>
#include <unordered_set>
#include <unordered_map>
#include <boost/heap/fibonacci_heap.hpp>
using namespace std;
using ll = long long;
using Edge = tuple<ll, ll, double>;
using ADJ_LIST = vector<vector<pair<ll, double> > >;
using Item = pair<double, ll>;
using Fiboheap = boost::heap::fibonacci_heap<Item, boost::heap::compare<greater<Item> > >;
const double INF = numeric_limits<double>::infinity();
pair<vector<ll>, vector<ll> > FindPivots(double B, vector<ll> S, const ADJ_LIST& adj, vector<double>& dist, ll k, ll t)
{
unordered_set<ll> U;
for(auto i: S) U.insert(i);
unordered_set<ll> bef = U;
for(ll tr = 1; tr <= k; tr++)
{
unordered_set<ll> 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<double, vector<ll> > BMSSP(ll l, vector<ll> S, double B, const ADJ_LIST& adj, vector<double>& dist, ll k, ll t)
{
assert(S.size() <= 1LL<<(l*t));
if(l == 0)
{
ll s = S.front();
vector<ll> U;
Fiboheap pq; unordered_map<ll, optional<Fiboheap::handle_type> > 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<ll> 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<vector<pair<int, double> > > adj(n + 1);
vector<Edge> 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<double> dist(n + 1, INF);
vector<vector<ll> > renum(n + 1);
ll c = 0;
using Item = pair<double, ll>;
priority_queue<Item, vector<Item>, greater<Item> > pq;
vector<bool> 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<double> dist(2*m+1, INF);
dist[s] = 1;
auto [B_, U] = BMSSP(l, {s}, INF, adj, dist, k, t);
vector<double> 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';
}

View File

@@ -1,12 +1,16 @@
#include <boost/heap/fibonacci_heap.hpp>
#include <iomanip>
#include <iostream>
#include <limits>
#include <queue>
#include <utility>
#include <vector>
using namespace std;
using ll = long long;
using Item = pair<double, ll>;
using Fiboheap = boost::heap::fibonacci_heap<Item, boost::heap::compare<greater<Item> > >;
const double INF = numeric_limits<double>::infinity();
int main() {
@@ -27,24 +31,28 @@ int main() {
vector<double> dist(n + 1, INF);
using Item = pair<double, ll>;
priority_queue<Item, vector<Item>, greater<Item> > pq;
Fiboheap pq;
vector<bool> chk(n + 1);
vector<Fiboheap::handle_type> 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';
}

51
src/dijk2/main.cpp Normal file
View File

@@ -0,0 +1,51 @@
#include <iomanip>
#include <iostream>
#include <limits>
#include <queue>
#include <utility>
#include <vector>
using namespace std;
using ll = long long;
const double INF = numeric_limits<double>::infinity();
int main() {
std::ios::sync_with_stdio(false);
ll n, m;
cin >> n >> m;
vector<vector<pair<int, double> > > 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<double> dist(n + 1, INF);
using Item = pair<double, ll>;
priority_queue<Item, vector<Item>, greater<Item> > pq;
vector<bool> 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';
}