update dijk & bsb
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,5 +1,5 @@
|
||||
build/
|
||||
.cache
|
||||
.compile_commands.json
|
||||
compile_commands.json
|
||||
|
||||
.DS_Store
|
||||
16
Makefile
16
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),)
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
@@ -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());
|
||||
|
||||
144
src/bsb/main.cpp
144
src/bsb/main.cpp
@@ -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';
|
||||
}
|
||||
@@ -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
51
src/dijk2/main.cpp
Normal 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';
|
||||
}
|
||||
Reference in New Issue
Block a user