Skip to content

Commit

Permalink
Merge pull request yosupo06#1219 from robinyqc/feature-branch
Browse files Browse the repository at this point in the history
Add Problem: Minimum Diameter Spanning Tree
  • Loading branch information
maspypy authored Aug 19, 2024
2 parents 89404f1 + bd3783e commit b591a8c
Show file tree
Hide file tree
Showing 15 changed files with 672 additions and 0 deletions.
78 changes: 78 additions & 0 deletions graph/minimum_diameter_spanning_tree/checker.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#include "testlib.h"
using namespace std;

using i32 = int;
using i64 = long long;
using u32 = unsigned int;
using u64 = unsigned long long;

template<typename T> using vec = vector<T>;

struct Edge
{
u32 a, b, c;
};

u64 read_ans(u32 n, u32 m, const vec<Edge> edges, InStream &stream)
{
u64 answer = stream.readUnsignedLong();
vec<vec<pair<u32, u32>>> g(n);
for (u32 i = 0; i < n - 1; i++)
{
u32 ei = stream.readInt(0, m - 1);
auto [u, v, w] = edges[ei];
g[u].emplace_back(v, w);
g[v].emplace_back(u, w);
}
u64 mdep = 0;
u32 p = 0;
u32 cnt = 0;
vec<bool> vis(n);
auto dfs = [&](auto &&f, u32 x, u64 dep) -> void
{
cnt++;
vis[x] = true;
for (auto [v, w]: g[x]) if (!vis[v]) {
f(f, v, dep + w);
}
if (dep > mdep) mdep = dep, p = x;
};
dfs(dfs, 0, 0);
quitif(cnt != n, _wa, "The output scheme is not a tree.");
mdep = 0;
vis.assign(n, false);
dfs(dfs, p, 0);
quitif(mdep != answer, _wa, "X (which is equal to " U64 ") is not equal to the diameter of the output scheme (which is equal to " U64 ").", answer, mdep);
return answer;
}

int main(int argc, char *argv[])
{
setName("compare mdst");
registerTestlibCmd(argc, argv);

// input
u32 n = inf.readInt();
u32 m = inf.readInt();
vector<Edge> edges(m);
for (u32 i = 0; i < m; i++)
{
u32 a = inf.readInt();
u32 b = inf.readInt();
u32 c = inf.readInt();
edges[i] = {a, b, c};
}

u64 x_ans = read_ans(n, m, edges, ans);
u64 x_ouf = read_ans(n, m, edges, ouf);

if (x_ans < x_ouf)
{
quitf(_wa, "There is a better solution");
}
if (x_ans > x_ouf)
{
quitf(_fail, "Participant finds better answer");
}
quitf(_ok, "OK: " U64, x_ouf);
}
8 changes: 8 additions & 0 deletions graph/minimum_diameter_spanning_tree/gen/example_00.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
4 7
0 1 1
0 1 2
1 1 0
0 2 2
1 2 2
0 3 1
2 3 3
4 changes: 4 additions & 0 deletions graph/minimum_diameter_spanning_tree/gen/example_01.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
4 3
0 1 1
1 2 2
3 1 3
6 changes: 6 additions & 0 deletions graph/minimum_diameter_spanning_tree/gen/example_02.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
6 5
0 1 1000000000
1 2 1000000000
2 3 1000000000
3 4 1000000000
4 5 1000000000
1 change: 1 addition & 0 deletions graph/minimum_diameter_spanning_tree/gen/example_03.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1 0
41 changes: 41 additions & 0 deletions graph/minimum_diameter_spanning_tree/gen/max_random.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#include <iostream>
#include "random.h"
#include "../params.h"

using namespace std;

struct E
{
int from, to, cost;
};

int main(int, char *argv[])
{
long long seed = atoll(argv[1]);
auto gen = Random(seed);

int n = gen.uniform(N_MAX - 100, N_MAX);
int m = gen.uniform(n - 1, (int)M_MAX);

vector<E> edges;
for (int i = 1; i < n; i++)
{
int c = gen.uniform(0LL, C_MAX);
edges.push_back({gen.uniform(0, i - 1), i, c});
}
for (int i = n - 1; i < m; i++)
{
int a = gen.uniform(0, n - 1);
int b = gen.uniform(0, n - 1);
int c = gen.uniform(0LL, C_MAX);
edges.push_back({a, b, c});
}

auto idx = gen.perm<int>(n);
printf("%d %d\n", n, m);
for (auto e : edges)
{
printf("%d %d %d\n", idx[e.from], idx[e.to], e.cost);
}
return 0;
}
41 changes: 41 additions & 0 deletions graph/minimum_diameter_spanning_tree/gen/random.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#include <iostream>
#include "random.h"
#include "../params.h"

using namespace std;

struct E
{
int from, to, cost;
};

int main(int, char *argv[])
{
long long seed = atoll(argv[1]);
auto gen = Random(seed);

int n = gen.uniform(1LL, N_MAX);
int m = gen.uniform(n - 1, (int)M_MAX);

vector<E> edges;
for (int i = 1; i < n; i++)
{
int c = gen.uniform(0LL, C_MAX);
edges.push_back({gen.uniform(0, i - 1), i, c});
}
for (int i = n - 1; i < m; i++)
{
int a = gen.uniform(0, n - 1);
int b = gen.uniform(0, n - 1);
int c = gen.uniform(0LL, C_MAX);
edges.push_back({a, b, c});
}

auto idx = gen.perm<int>(n);
printf("%d %d\n", n, m);
for (auto e : edges)
{
printf("%d %d %d\n", idx[e.from], idx[e.to], e.cost);
}
return 0;
}
43 changes: 43 additions & 0 deletions graph/minimum_diameter_spanning_tree/gen/small.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include <iostream>
#include "random.h"
#include "../params.h"

#define SMALL_N_MAX 1000

using namespace std;

struct E
{
int from, to, cost;
};

int main(int, char *argv[])
{
long long seed = atoll(argv[1]);
auto gen = Random(seed);

int n = gen.uniform(1, SMALL_N_MAX);
int m = gen.uniform(n - 1, (int)M_MAX);

vector<E> edges;
for (int i = 1; i < n; i++)
{
int c = gen.uniform(0LL, C_MAX);
edges.push_back({gen.uniform(0, i - 1), i, c});
}
for (int i = n - 1; i < m; i++)
{
int a = gen.uniform(0, n - 1);
int b = gen.uniform(0, n - 1);
int c = gen.uniform(0LL, C_MAX);
edges.push_back({a, b, c});
}

auto idx = gen.perm<int>(n);
printf("%d %d\n", n, m);
for (auto e : edges)
{
printf("%d %d %d\n", idx[e.from], idx[e.to], e.cost);
}
return 0;
}
43 changes: 43 additions & 0 deletions graph/minimum_diameter_spanning_tree/gen/small_c01.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include <iostream>
#include "random.h"
#include "../params.h"

#define SMALL_N_MAX 1000

using namespace std;

struct E
{
int from, to, cost;
};

int main(int, char *argv[])
{
long long seed = atoll(argv[1]);
auto gen = Random(seed);

int n = gen.uniform(1, SMALL_N_MAX);
int m = gen.uniform(n - 1, 2 * n);

vector<E> edges;
for (int i = 1; i < n; i++)
{
int c = gen.uniform(0, 1);
edges.push_back({gen.uniform(0, i - 1), i, c});
}
for (int i = n - 1; i < m; i++)
{
int a = gen.uniform(0, n - 1);
int b = gen.uniform(0, n - 1);
int c = gen.uniform(0, 1);
edges.push_back({a, b, c});
}

auto idx = gen.perm<int>(n);
printf("%d %d\n", n, m);
for (auto e : edges)
{
printf("%d %d %d\n", idx[e.from], idx[e.to], e.cost);
}
return 0;
}
34 changes: 34 additions & 0 deletions graph/minimum_diameter_spanning_tree/gen/star.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include <iostream>
#include "random.h"
#include "../params.h"

using namespace std;

struct E
{
int from, to, cost;
};

int main(int, char *argv[])
{
long long seed = atoll(argv[1]);
auto gen = Random(seed);

int n = N_MAX;
int m = n - 1;

vector<E> edges;
for (int i = 1; i < n; i++)
{
int c = gen.uniform(0LL, C_MAX);
edges.push_back({0, i, c});
}

vector<int> idx = gen.perm<int>(n);
printf("%d %d\n", n, m);
for (auto e : edges)
{
printf("%d %d %d\n", idx[e.from], idx[e.to], e.cost);
}
return 0;
}
52 changes: 52 additions & 0 deletions graph/minimum_diameter_spanning_tree/hash.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"example_00.in": "1906ab4c7a332b39d6c42bc2bfdbcb0c787a18a1f9a48aa2029efa2baae9fbff",
"example_00.out": "a9e891c47aa3fa35b34e103232cc50c4b8c6863420d74688ffaa7584204a3838",
"example_01.in": "4859c57ba64d8088c41b77c192a9535ac0682e0e478848d9a8fd238a2c4b7691",
"example_01.out": "1b2e99e121bafbc1a63ee56354dfeb88cf43d7a74668336e0a8ac3ade7d5202e",
"example_02.in": "026aafd663e40b9bbc108768553e0b89a3bf8130e4bdc46c29296f864c5e41bb",
"example_02.out": "f23935c24c3052e81dde866433d6e74da0a9948dbff35e6b7005daa3b937b9f4",
"example_03.in": "f4a8ae8e74ddfb896a256de4e3099911dcaa6a9302591713898069b0bcd6e3d7",
"example_03.out": "74d01a0c051c963d9a9b8ab9dbeab1723f0ad8534ea9fa6a942f358d7fa011b4",
"max_random_00.in": "74bf504bd6407b1c7b8c09f74173c08a402153e4a6e2fe55002908bfe340b7b4",
"max_random_00.out": "a185af522e31c2774d25f2a29fce5d3222ab6ce70d3049d75cdf0d112f45541b",
"max_random_01.in": "80e13dd93eb06c6cc690f0519687738f98bd9179189e8e1fa6c816a77a6be6a3",
"max_random_01.out": "110dd8adba49bcb77a138145770ad179dcc09a96e9e165ff654f74b448fc9aab",
"max_random_02.in": "40d2fb9765628f769c9ba55c18793e6db406f3812d2ac9fe855be5fd19b93fd1",
"max_random_02.out": "c886eb09b3e17942ea4b121aa9865b54d85596ef7067cf1e8034170767a468f0",
"max_random_03.in": "d33b0ac26f5056cb078aa8e343171c53dc81ca8b71927c62fc382a53f9c33481",
"max_random_03.out": "9e6e2d08a9f1a687b622b27934e32ed41e324b9441dafa4fc2487e27acee73ec",
"max_random_04.in": "4c5c60ca2ffb69dd1b6cb0dad89d8228ca29916a60e29771676227cf00321dd3",
"max_random_04.out": "89a0345bf86995a4c8eaf67614a37638a011a4a66a82d551715717f7a7924118",
"random_00.in": "a7829e3478fcbecbef9374f2d35301ff7c5d07b07bb2bfd382ec98b24e8f8a1a",
"random_00.out": "9be2eeebdfadb7b0ad27f0593cd460c13b7df01e4fa651861edcb25e00bf8831",
"random_01.in": "78d38cd756fd1531afee51031a14d58491ef905b49958a558b494e3fcc0aae9b",
"random_01.out": "d8ab5a5ad8d62fa3411fee3f13884f539a0c8853c4db04ff0b3042869083e7e8",
"random_02.in": "1019e11919c050da82f507a39ba60cb7a41f891aa84e2bbf9ffb40aabe50bf9f",
"random_02.out": "869e7df0ce29b4ed3b34945be3ec64c6a5bb61ae4e2aed51ec92be8eb80a1d48",
"random_03.in": "578e1f42b3f77c1945bf9babf81d3b48bdec19fbddc9e42900ec43700946f32b",
"random_03.out": "9b709f8aa05e69b4d118148649363b1908363b6c1395d32618f4966690473d3d",
"random_04.in": "68c46efae902d0d2102c3a0f7c28d7e316e5200165e70e3480cd5ceb75d6c823",
"random_04.out": "a45d99fbb3a400dbe1408aeb5e354fc83b259b8207b6277f9c3305ed20051321",
"small_00.in": "a7829e3478fcbecbef9374f2d35301ff7c5d07b07bb2bfd382ec98b24e8f8a1a",
"small_00.out": "9be2eeebdfadb7b0ad27f0593cd460c13b7df01e4fa651861edcb25e00bf8831",
"small_01.in": "78d38cd756fd1531afee51031a14d58491ef905b49958a558b494e3fcc0aae9b",
"small_01.out": "d8ab5a5ad8d62fa3411fee3f13884f539a0c8853c4db04ff0b3042869083e7e8",
"small_02.in": "1019e11919c050da82f507a39ba60cb7a41f891aa84e2bbf9ffb40aabe50bf9f",
"small_02.out": "869e7df0ce29b4ed3b34945be3ec64c6a5bb61ae4e2aed51ec92be8eb80a1d48",
"small_03.in": "23117fcb2d2c7be6acbcfe66b8734fac979e086fa97a0868ccf8f393179976e1",
"small_03.out": "119453fdae3adb56c944cd2da3d97e68d7e9e99521c7792b8d52ddb0c2f509ed",
"small_04.in": "68c46efae902d0d2102c3a0f7c28d7e316e5200165e70e3480cd5ceb75d6c823",
"small_04.out": "a45d99fbb3a400dbe1408aeb5e354fc83b259b8207b6277f9c3305ed20051321",
"small_c01_00.in": "d6ae2e7f8aab2edb91bd490c49f78935a8de13bdd6a98706535aeb404488f5f4",
"small_c01_00.out": "e1ce9d526bf31f320aae9b591db320c1e93dd7a3976893d0a731911e7abdd106",
"small_c01_01.in": "adba72e6de177bfb7b20342c7ee7ba64d59a56038d8c28db221d6d68cf6f0160",
"small_c01_01.out": "eb75c1d57bda02b7ccaf68d3dfeef098d9bafb536fd3e44ca0743f217a1ca934",
"small_c01_02.in": "c9ce0284afdc5d36aa3f6db85e2d1181c577257f1a4d66f939b2caa7f0180a2a",
"small_c01_02.out": "7fe2b7a08613c3a5ef8ee904ea986dd37c22fe5d4e78e94ea4e991e99705c95b",
"small_c01_03.in": "b2d2764bb9f05bdda5ee45c40685bae660dcca23a673ba1290c43387dc449c64",
"small_c01_03.out": "edfe92af334607d2d913b1a6697c84ed99c3c0b58c7ad300f43bb16f337af109",
"small_c01_04.in": "aece442481b2b2fd40bcaaf5373afbb575c933f71abfd8b0235d84aeead3398f",
"small_c01_04.out": "60738262a5f61b9fa296550ca6c1bcb733df7d7f763ceb1c0bd931d6b610f027",
"star_00.in": "81b438e159e15c233c087490f20502a0e77e124bef98340ae58d7ea44b893d0d",
"star_00.out": "604f980cba78c17f6070d24048891102d874a3ae3070862d1cc106995da102be"
}
27 changes: 27 additions & 0 deletions graph/minimum_diameter_spanning_tree/info.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
title = 'Minimum Diameter Spanning Tree'
timelimit = 5.0
forum = "https://github.com/yosupo06/library-checker-problems/issues/1208"

[[tests]]
name = "example.in"
number = 4
[[tests]]
name = "random.cpp"
number = 5
[[tests]]
name = "max_random.cpp"
number = 5
[[tests]]
name = "small.cpp"
number = 5
[[tests]]
name = "small_c01.cpp"
number = 5
[[tests]]
name = "star.cpp"
number = 1

[params]
N_MAX = 2_000
M_MAX = 2_000
C_MAX = 1_000_000_000
Loading

0 comments on commit b591a8c

Please sign in to comment.