Skip to content

Commit

Permalink
Merge pull request #838 from shirotsume4/makenewproblem_clique
Browse files Browse the repository at this point in the history
[問題追加] Enumerate Cliques
  • Loading branch information
yosupo06 committed Aug 20, 2022
2 parents 4a8d3c1 + d853418 commit 7da8c69
Show file tree
Hide file tree
Showing 18 changed files with 684 additions and 0 deletions.
62 changes: 62 additions & 0 deletions graph/enumerate_cliques/checker.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// https://github.com/MikeMirzayanov/testlib/blob/master/checkers/wcmp.cpp

// The MIT License (MIT)

// Copyright (c) 2015 Mike Mirzayanov

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include "testlib.h"

using namespace std;

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

int n = 0;
string j, p;

while (!ans.seekEof() && !ouf.seekEof())
{
n++;

ans.readWordTo(j);
ouf.readWordTo(p);

if (j != p)
quitf(_wa, "%d%s words differ - expected: '%s', found: '%s'", n, englishEnding(n).c_str(), compress(j).c_str(), compress(p).c_str());
}

if (ans.seekEof() && ouf.seekEof())
{
if (n == 1)
quitf(_ok, "\"%s\"", compress(j).c_str());
else
quitf(_ok, "%d tokens", n);
}
else
{
if (ans.seekEof())
quitf(_wa, "Participant output contains extra tokens");
else
quitf(_wa, "Unexpected EOF in the participants output");
}
}
54 changes: 54 additions & 0 deletions graph/enumerate_cliques/gen/erdos_renyi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#include "random.h"
#include <algorithm>
#include <cassert>
#include <cstdio>
#include <set>
#include <utility>
#include <vector>

void erdos_renyi(int n, int m, Random &gen) {
assert(static_cast<long long>(n) * (n - 1) / 2 >= m);

std::vector<int> xs(n);
for (auto &x : xs) {
x = gen.uniform<int>(0, MOD - 1);
}

std::vector<std::pair<int, int>> edges(m);
if (static_cast<long long>(n) * (n - 1) / 2 > m * 2) {
// sparse
std::set<std::pair<int, int>> eset;
for (auto &e : edges) {
do {
e = gen.uniform_pair(0, n - 1);
} while (!eset.insert(std::minmax(e.first, e.second)).second);
}
} else {
// dense
std::vector<std::pair<int, int>> all;
for (int u = 0; u < n; ++u) {
for (int v = 0; v < u; ++v) {
if (gen.uniform_bool()) {
all.emplace_back(u, v);
} else {
all.emplace_back(v, u);
}
}
}
gen.shuffle(all.begin(), all.end());
std::copy(all.begin(), all.begin() + m, edges.begin());
}

std::printf("%d %d\n", n, m);
for (int i = 0; i < n; ++i) {
std::printf("%d", xs[i]);
if (i != n - 1) {
std::printf(" ");
} else {
std::printf("\n");
}
}
for (const auto &e : edges) {
std::printf("%d %d\n", e.first, e.second);
}
}
4 changes: 4 additions & 0 deletions graph/enumerate_cliques/gen/example_00.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
3 2
1 2 3
0 1
1 2
11 changes: 11 additions & 0 deletions graph/enumerate_cliques/gen/example_01.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
5 9
97644645 128903910 346967627 176460807 156955500
0 1
0 2
0 3
0 4
1 2
1 3
1 4
2 3
2 4
15 changes: 15 additions & 0 deletions graph/enumerate_cliques/gen/large_random.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include "../params.h"
#include "./erdos_renyi.h"
#include "random.h"
#include <algorithm>

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

int n = gen.uniform<int>(N_MIN, N_MAX);
int m = gen.uniform<int>(
M_MIN, std::min(M_MAX, static_cast<long long>(n) * (n - 1) / 2));

erdos_renyi(n, m, gen);
}
15 changes: 15 additions & 0 deletions graph/enumerate_cliques/gen/large_sparse.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include "../params.h"
#include "./erdos_renyi.h"
#include "random.h"
#include <algorithm>

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

int n = gen.uniform<int>(10, 20);
int m = gen.uniform<int>(
(int)(std::min(M_MAX, static_cast<long long>(n) * (n - 1) / 2) * 0.9), std::min(M_MAX, static_cast<long long>(n) * (n - 1) / 2));

erdos_renyi(n, m, gen);
}
16 changes: 16 additions & 0 deletions graph/enumerate_cliques/gen/max_complete.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include "../params.h"
#include "./erdos_renyi.h"
#include "random.h"

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

int n = N_MIN;
while (n < N_MAX && n * (n + 1) / 2 <= M_MAX) {
n += 1;
}
int m = n * (n - 1) / 2;

erdos_renyi(n, m, gen);
}
13 changes: 13 additions & 0 deletions graph/enumerate_cliques/gen/max_random.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include "../params.h"
#include "./erdos_renyi.h"
#include "random.h"

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

int n = N_MAX;
int m = M_MAX;

erdos_renyi(n, m, gen);
}
3 changes: 3 additions & 0 deletions graph/enumerate_cliques/gen/minimum_00.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
2 1
1 2
0 1
18 changes: 18 additions & 0 deletions graph/enumerate_cliques/gen/small_dense.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include "../params.h"
#include "./erdos_renyi.h"
#include "random.h"

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

int N_MAX_2 = 1;
while (N_MAX_2 < N_MAX && N_MAX_2 * (N_MAX_2 + 1) / 2 <= M_MAX) {
N_MAX_2 += 1;
}

int n = gen.uniform<int>(N_MIN, N_MAX_2);
int m = gen.uniform<int>(M_MIN, n * (n - 1) / 2);

erdos_renyi(n, m, gen);
}
20 changes: 20 additions & 0 deletions graph/enumerate_cliques/gen/small_sparse.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include "../params.h"
#include "./erdos_renyi.h"
#include "random.h"
#include <algorithm>

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

int N_MAX_2 = 1;
while (N_MAX_2 < N_MAX && N_MAX_2 * (N_MAX_2 + 1) / 2 <= M_MAX) {
N_MAX_2 += 1;
}

int n = gen.uniform<int>(N_MIN, N_MAX_2);
int m =
gen.uniform<int>((int)(std::min<int>({M_MAX, n * 2, n * (n - 1) / 2}) * 0.86), std::min<int>({M_MAX, n * 2, n * (n - 1) / 2}));

erdos_renyi(n, m, gen);
}
48 changes: 48 additions & 0 deletions graph/enumerate_cliques/gen/star.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include "../params.h"
#include "random.h"
#include <algorithm>
#include <cstdio>
#include <utility>

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

int n = std::min(N_MAX, M_MAX + 1);
int m = n - 1;

std::vector<int> xs(n);
for (auto &x : xs) {
x = gen.uniform<int>(0, MOD - 1);
}

int center = gen.uniform(0, n - 1);

std::vector<std::pair<int, int>> edges;
for (int i = 0; i < n; ++i) {
if (i != center) {
edges.emplace_back(center, i);
}
}

for (auto &e : edges) {
if (gen.uniform_bool()) {
std::swap(e.first, e.second);
}
}

gen.shuffle(edges.begin(), edges.end());

std::printf("%d %d\n", n, m);
for (int i = 0; i < n; ++i) {
std::printf("%d", xs[i]);
if (i != n - 1) {
std::printf(" ");
} else {
std::printf("\n");
}
}
for (const auto &e : edges) {
std::printf("%d %d\n", e.first, e.second);
}
}
48 changes: 48 additions & 0 deletions graph/enumerate_cliques/hash.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"example_00.in": "a08b23fec03c86892e7baafeccb1146a0557e83068b92794f8d545a8e586ad23",
"example_00.out": "9a92adbc0cee38ef658c71ce1b1bf8c65668f166bfb213644c895ccb1ad07a25",
"example_01.in": "3d6fa8c24b7ad93c4c93fa8eb7291a5938fb79c24ca40eea0f397c49e6b035c5",
"example_01.out": "8b732b7a5ea0e25e27750733264a0a6bdbf58f7e5ffac39757309058647ae3c3",
"large_random_00.in": "815555ed9e2ba53c11c31d0b67b01957a36127098d1fc60d38fabcda3d28c460",
"large_random_00.out": "642779bac3275da6a744d8cb4136fc76160c245166533cc1041aad0e73fe1402",
"large_random_01.in": "f82ec93ee5af9f144a9524e33b92a9db7c331ef1d6f30fc424ca065586098d64",
"large_random_01.out": "ba885576c39239424d3e3700a055e1703708e1aaa7de155fe385a209a42c9316",
"large_random_02.in": "b40aca6c020d98a6468e1edefa54f01a6a62af452b79fc366d116bab1059604e",
"large_random_02.out": "6b4b2f622668620f0566adbf6844add3a1f3ba52cd53256a3eaa2edaa6a9dff5",
"large_sparse_00.in": "ef953c49b2ceea77833b0d50c3752d490e461b8f89990cf79319cef4b632303b",
"large_sparse_00.out": "61032ac673068dcd15c0180a514ffd748eb3930a46b18ef3dce019c42bc5b488",
"large_sparse_01.in": "94a42d80999b05857e5a9005432de3abb3cc56912d49d040ebd24b6b19126c61",
"large_sparse_01.out": "c2967e6cae51bcb55507971b98f2479436b333c81e845702ccf8400e866c27d9",
"large_sparse_02.in": "5427d8af43c4fbf473c7f86eb5420d9e186c5866d035002ac2c0b353b6dec299",
"large_sparse_02.out": "f7342548f7e314badfc8ada45347ac18c149c05f41ae47e211cf7d4a08492465",
"large_sparse_03.in": "8adb7d668a33b88e83270c6dce49b6630e3d6d664bee34162ddfd5ac881d0339",
"large_sparse_03.out": "868c175445b18f67e3878123ef27583eb3f6eb7b28893371e2b4769a719cd8b1",
"large_sparse_04.in": "8e4a9a3df1699b583f074eae60e235b2ecb3a96fc164adf74035e0efc0c6ffa9",
"large_sparse_04.out": "c420108720d891ca17395f19e3ee13b5002c63abd008b7d538c13d5f0de9a5e2",
"max_complete_00.in": "f6141f0e896be38ce58045800976a0681f28602ff9852c3565c8b60f3f80b074",
"max_complete_00.out": "e08c4b0689e39a4b1185f5aa13d1b5f8ae804bb6601f9eb545d1c7b3c4d5b88f",
"max_random_00.in": "48b4383032e6157d5ae4cb0cf685ddd6ddf3a80c0815fe6595f15825aa5adf6f",
"max_random_00.out": "8af1ac3113a361af4752d6d1f43d628ef86b6a50d6526ed4a082a48cd860cc10",
"max_random_01.in": "37c00fbedbccd482c9e09f038364ef010b24e6ff6afc998ab77ae7669133306b",
"max_random_01.out": "adcda1dd0384e8cec2354b478328518be0aeb2972638fda72745005caae992fe",
"max_random_02.in": "224b255b6f658631f4c9678ce5cddc00168c1569aa6e7559b7f015282cf11e80",
"max_random_02.out": "0dcac6f97870c018dd7074349f064e1520c883c9fd25007ea128cc90cb1a13ab",
"minimum_00.in": "5982244103c9d82ae9b5fcdf1e6fcccecb3da77fee1facd7e8736b0602d35448",
"minimum_00.out": "f0b5c2c2211c8d67ed15e75e656c7862d086e9245420892a7de62cd9ec582a06",
"small_dense_00.in": "17a47f1c5b26f077d0aa1fa23fab79d4fb284620eb3f2b14a4594e70b54c14ba",
"small_dense_00.out": "4c81fa5d3d134e48a8d46ab7ae9a1d151a53e3d9effaa9a6de833e27a79a72ac",
"small_dense_01.in": "60d2002862290ab22e45f9c936d606949eba822218ca627d0866188b02513663",
"small_dense_01.out": "297a3f08b160550f9d77c8c01eeda58a721925a4f5a3fa73ce49479dc33b2331",
"small_dense_02.in": "b0455b403180032d91f883fdf5a6b6a87c1105db847f845c8c89913af5239247",
"small_dense_02.out": "a1f37de7239807c245a41fe4506e313efbbe625c00f9f86ac669ad0127519197",
"small_sparse_00.in": "d5c07856b715b51cc6fcdaf61686d7a5f08287bf57a8daa90e8503aca4eec4b2",
"small_sparse_00.out": "533be81fc181b9d8a5d3b0770b242974d2cc59c902342277897f0715766144d0",
"small_sparse_01.in": "c8cf89a9bf5bb7dec6e86afce60b17e0c6df326b1b151c8d98882701705bcf2f",
"small_sparse_01.out": "5ff3d817f68faadbafc107b5078900cd6aa4a302e64d9d8bab71c313868da986",
"small_sparse_02.in": "ce44d60378cdeed7db967056d6c8bda8e81e0d95965e09487a7b911844a8598c",
"small_sparse_02.out": "afb02ec0fe5d501e7b6947354095de929351a8b3df4e7355f27a383cdd391fb4",
"star_00.in": "be64b15b042580f8fe5023efb89dee50dbf729cc4f369a6c940bcc19802ad543",
"star_00.out": "b835f0c6462a1c07cfadbc0d3a50f0550795ac0315013f767e2f52e439dfebe4",
"star_01.in": "06cdde4800fa9b0478d839708a7b920a6f2093f8a1d68a621ec5027e09c7f7e9",
"star_01.out": "a5f664f82cd11ca779cf9ffcfe411f7bad86eb2ef08bea279903b6fed8f282fb"
}
42 changes: 42 additions & 0 deletions graph/enumerate_cliques/info.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
title = 'Enumerate Cliques'
timelimit = 5.0
forum = "https://github.com/yosupo06/library-checker-problems/issues/820"

[[tests]]
name = "example.in"
number = 2
[[tests]]
name = "minimum.in"
number = 1
[[tests]]
name = "small_sparse.cpp"
number = 3
[[tests]]
name = "small_dense.cpp"
number = 3
[[tests]]
name = "large_sparse.cpp"
number = 5
[[tests]]
name = "large_random.cpp"
number = 3
[[tests]]
name = "max_random.cpp"
number = 3
[[tests]]
name = "star.cpp"
number = 2
[[tests]]
name = "max_complete.cpp"
number = 1

[[solutions]]
name = 'naive.cpp'
wrong = true

[params]
N_MIN = 1
N_MAX = 100
M_MIN = 1
M_MAX = 100
MOD = 998_244_353
Loading

0 comments on commit 7da8c69

Please sign in to comment.