feat: new graph problem formatted.

This commit is contained in:
2026-05-25 19:53:45 -03:00
parent 8785966987
commit 4d583f8d8c
232 changed files with 10308 additions and 0 deletions

View File

@@ -0,0 +1,52 @@
// https://codeforces.com/problemset/problem/104/C
#include <bits/stdc++.h>
using namespace std;
using vi = vector<int>;
using ll = long long;
const int MAXN = 110;
vector<vi> g(MAXN);
bitset<MAXN> vis;
void dfs(int x){
vis[x]=1;
for(auto n: g[x]) if(!vis[n]) dfs(n);
}
void solve()
{
int n, m; cin >> n >> m;
for (int i=0;i<m;i++){
int u,v; cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
}
if (n != m) {
cout << "OFFLINE" << endl;
return;
}
vis.reset();
dfs(1);
for (int i=1;i<=n;i++){
if (!vis[i]) {
cout << "OFFLINE" << endl;
return;
}
}
cout << "ONLINE" << endl;
return;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
solve();
return 0;
}

View File

@@ -0,0 +1,60 @@
from collections import deque
def check_connectivity(adj, n):
vis = [False for _ in range(n)]
def dfs(x):
vis[x] = True
for v in adj[x]:
if not vis[v]:
dfs(v)
dfs(0)
return all(vis)
def check_cthulhu(adj, degree, n):
marked = [False for _ in range(n)]
dq = deque([])
for i, d in enumerate(degree):
if d == 1:
dq.append(i)
marked[i] = True
while len(dq) != 0:
i = dq.popleft()
for v in adj[i]:
if not marked[v]:
degree[v] -= 1
if degree[v] == 1:
dq.append(v)
marked[v] = True
# if all are marked it means that there was no cycle
if all(marked):
return False
# if some of the non-marked vertices does not have degree 2, it is not a simple cycle
for v in range(n):
if not marked[v] and degree[v] != 2:
return False
return True
n, m = map(int, input().split())
adj = [[] for _ in range(n)]
degree = [0] * n
for i in range(m):
u, v = map(int, input().split())
u -= 1
v -= 1
adj[u].append(v)
adj[v].append(u)
degree[u] += 1
degree[v] += 1
if not check_connectivity(adj, n) or not check_cthulhu(adj, degree, n):
print("OFFLINE")
else:
print("ONLINE")

View File

@@ -0,0 +1,26 @@
#include "testlib.h"
#include <string>
using namespace std;
const string YES = "ONLINE";
const string NO = "OFFLINE";
int main(int argc, char *argv[]) {
setName("%s", (YES + " or " + NO + " (case insensitive)").c_str());
registerTestlibCmd(argc, argv);
std::string ja = upperCase(ans.readWord());
std::string pa = upperCase(ouf.readWord());
if (ja != YES && ja != NO)
quitf(_fail, "%s or %s expected in answer, but %s found", YES.c_str(), NO.c_str(), compress(ja).c_str());
if (pa != YES && pa != NO)
quitf(_pe, "%s or %s expected, but %s found", YES.c_str(), NO.c_str(), compress(pa).c_str());
if (ja != pa)
quitf(_wa, "expected %s, found %s", compress(ja).c_str(), compress(pa).c_str());
quitf(_ok, "answer is %s", ja.c_str());
}

View File

@@ -0,0 +1,172 @@
#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;
const int MIN_N = 1;
const int MAX_N = 100;
const int rnd_test_n = 100;
template <typename T> void append(vector<T> &dest, const vector<T> &orig) {
dest.insert(dest.end(), orig.begin(), orig.end());
}
string output_tc(int n, int m, vector<pair<int, int>> &edges) {
ostringstream oss;
oss << n << " " << m << "\n";
vector<int> p(n + 1);
iota(p.begin(), p.end(), 0);
shuffle(p.begin() + 1, p.end());
shuffle(edges.begin(), edges.end());
for (const auto &edge : edges) {
int u = edge.first;
int v = edge.second;
if (rnd.next(2)) swap(u, v);
oss << p[u] << " " << p[v] << "\n";
}
return oss.str();
}
vector<pair<int, int>> generate_random_tree(int n) {
vector<pair<int, int>> edges;
for (int i = 2; i <= n; i++) {
int parent = rnd.next(1, i - 1);
edges.push_back({parent, i});
}
return edges;
}
string generate_valid_case(int n) {
if (n < 3) n = 3;
vector<pair<int, int>> edges;
int k = rnd.next(3, n);
for (int i = 1; i <= k; i++) {
int next_node = (i == k) ? 1 : i + 1;
edges.push_back({i, next_node});
}
for (int i = k + 1; i <= n; i++) {
int parent = rnd.next(1, i - 1);
edges.push_back({parent, i});
}
return output_tc(n, edges.size(), edges);
}
vector<string> generate_sample_tests() {
vector<string> tests;
vector<pair<int, int>> edges = {
{2, 3}, {1, 3}, {2, 1}, {3, 4}, {4, 5},
{4, 6}, {2, 7}, {7, 8}, {7, 9}, {1, 10},
{10, 11}, {11, 12}, {14, 9}, {13, 11}
};
tests.push_back(output_tc(14, 14, edges));
vector<pair<int, int>> e1 = {{1, 2}, {2, 3}, {3, 1}};
tests.push_back(output_tc(3, 3, e1));
vector<pair<int, int>> e2 = {{1, 2}, {2, 3}, {3, 4}};
tests.push_back(output_tc(4, 3, e2));
return tests;
}
vector<string> generate_manual_tests() {
vector<string> tests;
vector<pair<int, int>> e1 = {{1, 2}, {2, 3}};
tests.push_back(output_tc(3, 2, e1));
return tests;
}
string rnd_test(int i) {
int max_n = MAX_N;
if (i < rnd_test_n / 3) max_n = 8;
else if (i < rnd_test_n / 2) max_n = 30;
int n = rnd.next(3, max_n);
if (rnd.next(2)) {
return generate_valid_case(n);
} else {
int m_type = rnd.next(3);
vector<pair<int, int>> edges;
if (m_type == 0) {
edges = generate_random_tree(n);
} else if (m_type == 1) {
edges = generate_random_tree(n);
int max_possible_edges = n * (n - 1) / 2;
int edges_to_add = min(6, max_possible_edges - (n - 1));
set<pair<int, int>> existing;
for (auto &e : edges) {
existing.insert({min(e.first, e.second), max(e.first, e.second)});
}
while (edges_to_add > 0) {
int u = rnd.next(1, n);
int v = rnd.next(1, n);
if (u != v) {
pair<int, int> new_edge = {min(u, v), max(u, v)};
if (existing.find(new_edge) == existing.end()) {
existing.insert(new_edge);
edges.push_back(new_edge);
edges_to_add--;
}
}
}
} else {
if (n < 6) n = 6;
int metade = n / 2;
for (int k = 1; k <= metade; k++) {
edges.push_back({k, (k == metade) ? 1 : k + 1});
}
for (int k = metade + 1; k <= n; k++) {
edges.push_back({k, (k == n) ? metade + 1 : k + 1});
}
}
return output_tc(n, edges.size(), edges);
}
}
vector<string> generate_random_tests() {
vector<string> tests;
for (int i = 0; i < rnd_test_n; i++) {
tests.push_back(rnd_test(i));
}
return tests;
}
string extreme_test_1() {
return generate_valid_case(MAX_N);
}
vector<string> generate_extreme_tests() {
vector<string> tests;
tests.push_back(extreme_test_1());
return tests;
}
int main(int argc, char *argv[]) {
registerGen(argc, argv, 1);
vector<string> tests;
size_t test = 0;
append(tests, generate_sample_tests());
append(tests, generate_manual_tests());
append(tests, generate_random_tests());
append(tests, generate_extreme_tests());
for (const auto &t : tests) {
startTest(++test);
cout << t;
}
return 0;
}

View File

@@ -0,0 +1 @@
generator

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,39 @@
#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;
const int MIN_N = 1;
const int MAX_N = 100;
int main(int argc, char* argv[]) {
registerValidation(argc, argv);
int n = inf.readInt(MIN_N, MAX_N, "n");
inf.readSpace();
int max_possible_edges = (n * (n - 1)) / 2;
int m = inf.readInt(0, max_possible_edges, "m");
inf.readEoln();
set<pair<int, int>> existing_edges;
for (int i = 0; i < m; i++) {
int u = inf.readInt(1, n, "u");
inf.readSpace();
int v = inf.readInt(1, n, "v");
inf.readEoln();
ensuref(u != v, "self-loops are not allowed. vertice %d has a connection with it-self", u);
pair<int, int> edge = {min(u, v), max(u, v)};
ensuref(existing_edges.find(edge) == existing_edges.end(), "edge between %d and %d already exists", u, v);
existing_edges.insert(edge);
}
inf.readEof();
return 0;
}