feat: new graph problem partially formatted.

This commit is contained in:
2026-05-28 21:27:41 -03:00
parent 4d583f8d8c
commit d931bb6422
21 changed files with 6761 additions and 0 deletions

View File

@@ -52,6 +52,7 @@ Repositório com a formatação de problemas que exploram variadas técnicas de
- [Conversor Fonético Genérico](./conversor-fonetico-generico)
- [Knight Moves](./knight-moves)
- [Sliding Puzzle](./sliding-puzzle)
- [Pique Pega](./pique-pega/)
- [Lazy Jumping Frog](./ra-preguicosa/)
- [Rede Anel Estelar](./rede-anel-estelar/)

97
pique-pega/Makefile Normal file
View File

@@ -0,0 +1,97 @@
# Normal directories
SRC_DIR := src
BIN_DIR := bin
DBG_DIR := bin/debug
# Grader directories
GRADER := $(wildcard $(SRC_DIR)/grader.cpp)
GRADER_DIR := $(SRC_DIR)/grader
HANDLER_DIR := $(SRC_DIR)/handler
GRADER_SRC := $(wildcard $(GRADER_DIR)/*.cpp)
GRADER_BIN := $(patsubst $(GRADER_DIR)/%.cpp, $(BIN_DIR)/%, $(GRADER_SRC))
GRADER_DBG := $(patsubst $(GRADER_DIR)/%.cpp, $(DBG_DIR)/%, $(GRADER_SRC))
# Change CPP source directories if grader is defined
ifdef GRADER
SRC := $(wildcard $(HANDLER_DIR)/*.cpp)
BIN := $(patsubst $(HANDLER_DIR)/%.cpp, $(BIN_DIR)/%, $(SRC))
DBG := $(patsubst $(HANDLER_DIR)/%.cpp, $(DBG_DIR)/%, $(SRC))
else
SRC := $(wildcard $(SRC_DIR)/*.cpp)
BIN := $(patsubst $(SRC_DIR)/%.cpp, $(BIN_DIR)/%, $(SRC))
DBG := $(patsubst $(SRC_DIR)/%.cpp, $(DBG_DIR)/%, $(SRC))
endif
SRC_C := $(wildcard $(SRC_DIR)/*.c)
BIN_C := $(patsubst $(SRC_DIR)/%.c, $(BIN_DIR)/%, $(SRC_C))
DBG_C := $(patsubst $(SRC_DIR)/%.c, $(DBG_DIR)/%, $(SRC_C))
SRC_JAVA := $(wildcard $(SRC_DIR)/*.java)
BIN_JAVA := $(patsubst $(SRC_DIR)/%.java, $(BIN_DIR)/%.class, $(SRC_JAVA))
DBG_JAVA := $(patsubst $(SRC_DIR)/%.java, $(DBG_DIR)/%.class, $(SRC_JAVA))
CHECKER := $(wildcard $(SRC_DIR)/checker.cpp)
C := gcc
CPP := g++
CXX_FLAGS := -Wall -O2
DEBUG_FLAGS := -Wall -g
BOCA_FLAGS := -static -DBOCA_SUPPORT
JV = javac
JV_DEBUG = -g
JV_DIR = -d bin
JV_DBG_DIR = -d bin/debug
.PHONY: all debug release checker clean
all: debug release checker
debug: $(DBG) $(DBG_C) $(DBG_JAVA) $(GRADER_DBG)
release: $(BIN) $(BIN_C) $(BIN_JAVA) $(GRADER_BIN)
ifdef CHECKER
checker: $(DBG_DIR)/checker-boca $(BIN_DIR)/checker-boca
endif
$(BIN): $(BIN_DIR)/% : $(SRC_DIR)/%.cpp | $(BIN_DIR)
$(CPP) $(CXX_FLAGS) $^ -o $@
$(DBG): $(DBG_DIR)/% : $(SRC_DIR)/%.cpp | $(DBG_DIR)
$(CPP) $(DEBUG_FLAGS) $^ -o $@
$(BIN_C): $(BIN_DIR)/% : $(SRC_DIR)/%.c | $(BIN_DIR)
$(C) $(CXX_FLAGS) $^ -o $@
$(DBG_C): $(DBG_DIR)/% : $(SRC_DIR)/%.c | $(DBG_DIR)
$(C) $(DEBUG_FLAGS) $^ -o $@
$(BIN_JAVA): $(BIN_DIR)/%.class : $(SRC_DIR)/%.java | $(BIN_DIR)
$(JV) $(JV_DIR) $^
$(DBG_JAVA): $(DBG_DIR)/%.class : $(SRC_DIR)/%.java | $(DBG_DIR)
$(JV) $(JV_DEBUG) $(JV_DBG_DIR) $^
$(GRADER_BIN): $(BIN_DIR)/% : $(GRADER_DIR)/%.cpp $(GRADER) $(GRADER_DIR)/*.h
$(CPP) $(CXX_FLAGS) $^ -o $@
$(GRADER_DBG): $(DBG_DIR)/% : $(GRADER_DIR)/%.cpp $(GRADER) $(GRADER_DIR)/*.h
$(CPP) $(DEBUG_FLAGS) $^ -o $@
$(BIN_DIR):
mkdir -p $@
$(DBG_DIR):
mkdir -p $@
$(BIN_DIR)/checker-boca: $(SRC_DIR)/checker.cpp
$(CPP) $(CXX_FLAGS) $(BOCA_FLAGS) $^ -o $@
$(DBG_DIR)/checker-boca: $(SRC_DIR)/checker.cpp
$(CPP) $(DEBUG_FLAGS) $(BOCA_FLAGS) $^ -o $@
clean:
@echo Cleaning problem files
rm -rf bin

188
pique-pega/maratona.cls Normal file
View File

@@ -0,0 +1,188 @@
\ProvidesPackage{maratona}
\LoadClass[11pt]{article}
% remove page numbers
\pagenumbering{gobble}
\RequirePackage{fancyhdr}
\RequirePackage{tabularx,colortbl}
%\RequirePackage{arial}
\RequirePackage{ifpdf}
\RequirePackage[T1]{fontenc}
\RequirePackage[utf8]{inputenc}
\RequirePackage[portuguese]{babel}
\RequirePackage{graphics}
\RequirePackage{graphicx}
\RequirePackage{amssymb,amsmath,wrapfig}
\RequirePackage{xcolor,colortbl}
\RequirePackage{xcolor}
\RequirePackage{ifthen}
\oddsidemargin 0cm
\evensidemargin -2cm
\topmargin -1cm
\textwidth 16cm
\textheight 23cm
\ifpdf
\RequirePackage[pdftex]{hyperref}
\else
\RequirePackage[hypertex]{hyperref}
\fi
\newcommand{\var}[1]{\ensuremath{{#1}}}
\hypersetup{
letterpaper,
colorlinks=true,
linkcolor=blue,
urlcolor=blue,
pdfpagemode=none,
pdftitle={IV Maratona de Programação do IFB \today},
pdfauthor={},
pdfsubject={Caderno de problemas da IV Maratona de Programação do IFB },
pdfkeywords={maratona, programação, IFB}
}
\DeclareGraphicsExtensions{png}
\lhead{DS Contest Tools}
\pagestyle{fancy}
% Capa
\newenvironment{Maratona}[3]
{
\begin{titlepage}
\begin{center}
\vspace{1cm}
\Large{\textbf{#1}} \\
\vspace{1cm}
{\textbf{Caderno de Problemas}} \\
\vspace{1cm}
\begin{small}
\textsl{#2}
\end{small} \\
\begin{figure}[htp]
\begin{center}
\includegraphics[scale=1]{logos/logo-maratona.png}
\end{center}
\end{figure}
{(Este caderno contém {#3} problemas)} \\
\vspace{1cm}
}
{
\vfill
\begin{small}
{QNM 40, Área Especial nº 01,
Taguatinga/DF, 72146-000 ,
Brasil } \\
{Telefone (61) 2103-2200 \\http://www.ifb.edu.br/taguatinga} \\
\end{small}
\end{center}
\end{titlepage}
}
\newcommand{\Organizacao}[2]{
{\small \vfill
\begin{center}
\textbf{Comissão Organizadora:} \\
{#1} \\
\bigskip
\textbf{Apoio:}\\
{#2}
\end{center}
}
\vfill
}
% Problema
\newcounter{problem}
\newenvironment{Problema}[4]{
\stepcounter{problem}
\newpage
\begin{center}
\Large{\ifthenelse{\equal{#1}{}}{\textbf{{#2}}}{\textbf{Problema {#1} -- {#2} }}}{\\\footnotesize \textbf{Limite de tempo: {#3}s}}{\\[-0.1cm]\footnotesize \textbf{Limite de memória: {#4}MB}}
\end{center}
}
\newcounter{problemAutor}
\newenvironment{ProblemaAutor}[5]{
\stepcounter{problemAutor}
\newpage
\begin{center}
\Large{\ifthenelse{\equal{#1}{}}{\textbf{{#2}}}{\textbf{Problema {#1} -- {#2} }}}{\\\footnotesize \textbf{Limite de tempo: {#3}s}}{\\[-0.1cm]\footnotesize \textbf{Limite de memória: {#4}MB\\}}{
\footnotesize Autor: {#5}
}
\end{center}
}
% Código-fonte
\newcommand{\codigofonte}[1]{Nome do arquivo fonte: {#1}}
% Entrada
\newcommand{\Entrada}{
\bigskip
\begin{large}
\textbf{Entrada} \\
\end{large}
}
% Saida
\newcommand{\Saida}{
\bigskip
\begin{large}
\textbf{Saída} \\
\end{large}
}
\newcommand{\Interacao}{
\bigskip
\begin{large}
\textbf{Interação} \\
\end{large}
}
\newcommand{\Notas}{
\bigskip
\begin{large}
\textbf{Notas} \\
\end{large}
}
% Exemplo
\newenvironment{Exemplo}
{
\tabularx{\textwidth}{XX}
% {@{\extracolsep{\fill}}|l|l|}
% {|l|l@{\extracolsep{\fill}|}}
\hline
Entrada & Saída \\\hline
}
{
\hline
\endtabularx
}
% Exemplo de Entrada
\newenvironment{ExemploEntrada}
{
\bigskip
\begin{large}
\textbf{Exemplo} \\
\end{large}
}
{
}
% Sample Output

Binary file not shown.

View File

@@ -0,0 +1,33 @@
\documentclass[10pt]{article}
\usepackage[utf8]{inputenc}
\usepackage{amsmath,amsthm,amssymb}
\usepackage{fullpage}
\usepackage{url}
\pagenumbering{gobble}
\usepackage{hyperref}
\title{ Tutorial: Pique Pega}
\author{Arthur Andrade D'Olival}
\date{}
\begin{document}
\maketitle
O problema pode ser modelado como um jogo de perseguição em um grafo acíclico conectado, uma árvore. A vitória do Delegado é garantida de forma determinística se, e somente se, pelo menos uma das três propriedades estruturais abaixo for satisfeita. Caso contrário, a topologia da árvore garante ao Noivo uma estratégia de evasão infinita.
\begin{enumerate}
\item \textbf{Captura no Primeiro Turno:} Se a distância no grafo entre os vértices iniciais for $dist(a, b) \le d_a$, o Delegado alcança o Noivo imediatamente na sua primeira jogada. Essa distância pode ser calculada em $O(N)$ executando uma Busca em Largura (BFS) ou Busca em Profundidade (DFS) a partir do vértice $a$.
\item \textbf{Cobertura do Diâmetro da Árvore:} O Delegado vence se o diâmetro da árvore, o caminho mais longo entre quaisquer dois vertíces, for $D \le 2 \cdot d_a$.
\begin{itemize}
\item \textbf{Prova:} Em uma árvore de diâmetro $D$, o raio a partir de seu centro absoluto é $\lceil D/2 \rceil$. Se $D \le 2 \cdot d_a$, o Delegado pode simplesmente mover-se em direção ao vértice central da árvore. A partir desse centro, a distância máxima para qualquer outro vértice do grafo será $\le d_a$. Assim, o Delegado passa a cobrir todos os vértices possíveis em um único turno, não deixando zonas seguras para o Noivo.
\item \textbf{Cálculo:} O diâmetro pode ser encontrado linearmente em $O(N)$ usando duas execuções de BFS ou DFS: a primeira partindo de um nó arbitrário para encontrar o nó $u$ mais distante, e a segunda partindo de $u$ para encontrar o nó $v$ mais distante. A distância $dist(u, v)$ será o diâmetro $D$.
\end{itemize}
\item \textbf{Dominância de Raio de Ação:} O Delegado vence se a sua capacidade de movimento anular o potencial de salto do Noivo, o que ocorre estritamente quando $2 \cdot d_a \ge d_b$.
\begin{itemize}
\item \textbf{Prova:} Para que o Noivo consiga escapar de um cerco ao ser encurralado em uma extremidade da árvore, ele precisaria ser capaz de "pular por cima" da zona de controle do Delegado sem aterrissar dentro dela. Como o Delegado controla um raio de $d_a$ ao seu redor, o diâmetro da sua zona de ameaça é $2 \cdot d_a$. Para cruzar essa zona com segurança e ainda ganhar distância, o Noivo precisaria de um salto estritamente maior que a zona de perigo, ou seja, $d_b > 2 \cdot d_a$.
Se essa condição de salto falha, o Delegado pode gradualmente empurrar o Noivo para uma folha da árvore e capturá-lo, reduzindo a distância entre eles a cada turno.
\end{itemize}
\end{enumerate}
Se nenhuma dessas três condições for satisfeita ($dist(a, b) > d_a$, $D > 2 \cdot d_a$ e $d_b > 2 \cdot d_a$), o Noivo sempre terá espaço topológico para manter uma distância de segurança superior a $d_a$ após o seu turno, configurando um jogo infinito.
A complexidade de tempo total para verificar todas as condições e decidir o vencedor é $O(N)$.\end{document}

BIN
pique-pega/pique-pega.pdf Normal file

Binary file not shown.

35
pique-pega/pique-pega.tex Normal file
View File

@@ -0,0 +1,35 @@
\documentclass{maratona}
\begin{document}
\begin{ProblemaAutor}{}{Pique Pega}{1}{256}{Arthur Andrade D'Olival}
No grande Arraiá de São João, o aguardado Casamento Caipira virou uma tremenda confusão!
O \textbf{Noivo} entrou em pânico na hora do "sim" e fugiu correndo.
Imediatamente, o \textbf{Delegado} da festa foi acionado pelo pai da noiva para capturar o fujão e arrastá-lo direto para a barraca da Cadeia.
O local da festa possui uma organização bem tradicional: o arraiá é composto por $n$ barracas numeradas de $1$ a $n$, que são conectadas por exatamente $n-1$ corredores de terra batida decorados com bandeirinhas coloridas.
A organização foi feita de tal forma que existe sempre um único caminho simples caminhando pelos corredores entre quaisquer duas barracas.
A perseguição começa com o Delegado na barraca $a$, e o Noivo escondido na barraca $b$. Eles correm em turnos alternados, e o \textbf{Delegado dá o primeiro pique de corrida}.
\begin{itemize}
\item No seu turno, o \textbf{Delegado} pode correr por até $d_a$ corredores de bandeirinhas para tentar encurralar o fujão.
\item Na sua vez, o \textbf{Noivo} pode disparar por até $d_b$ corredores para tentar se afastar da autoridade.
\end{itemize}
A distância entre duas barracas é o número de corredores no único caminho entre elas.
No desespero (ou para comer uma paçoca), ambos podem optar por não correr e permanecer na mesma barraca durante o seu turno.
O movimento é focado apenas no destino: eles cruzam os corredores sem parar nas barracas intermediárias.
O Delegado vence se, em até $10^{100}$ turnos, conseguir chegar na \textbf{mesma barraca} que o Noivo, efetuando a prisão.
Caso contrário, se o Noivo conseguir sambar pelo arraiá e despistar o Delegado a noite inteira, o Noivo vence, e continua solteiro.
Sua tarefa é determinar quem sairá vencedor dessa confusão junina, assumindo que tanto o Delegado quanto o Noivo corram e se escondam de maneira absolutamente ótima.
Para cada caso de teste, imprima uma única linha contendo o vencedor dessa perseguição caipira: \texttt{Delegado} ou \texttt{Noivo}.
\Notas
Problema adaptado de \href{https://codeforces.com/contest/1405/problem/D}{Codeforces Round 668 (Div. 2, Problem D)}.\end{ProblemaAutor}
\end{document}

64
pique-pega/problem.json Normal file
View File

@@ -0,0 +1,64 @@
{
"version": "1.0",
"problem": {
"title": "Pique Pega",
"event": "",
"time_limit": 1.0,
"memory_limit_mb": 256,
"input_file": "stdin",
"output_file": "stdout",
"interactive": false,
"grader": false,
"subject": {
"en_us": [
"bfs", "dfs", "graph-diameter"
],
"pt_br": [
"busca-em-largura", "busca-em-profundidade", "diametro-de-grafo"
],
"es": [
""
]
}
},
"author": {
"name": "Arthur Andrade D'Olival",
"affiliation": "",
"country": "",
"email": ""
},
"build": {
"run_generator": false,
"run_validator": true,
"produce_outputs": true,
"run_checker": true,
"run_all_solutions": true,
"run_specific_solution": "",
"generate_io_only": false,
"generate_pdf_only": false,
"cpu_count": 1,
"build_pdf": true,
"pdf_format": "ds",
"io_samples": 0
},
"solutions": {
"main-ac": "ac.cpp",
"alternative-ac": ["alternative-ac.py"],
"wrong-answer": [],
"time-limit": [],
"time-limit-or-ac": [],
"time-limit-or-memory-limit": [],
"memory-limit": [],
"presentation-error": [],
"runtime-error": []
},
"polygon_config": {
"id": ""
},
"boca_config": {
"time_limit": 1,
"number_of_repetitions": 1,
"maximum_memory_mb": 512,
"maximum_output_size_kb": 24096
}
}

96
pique-pega/src/ac.cpp Normal file
View File

@@ -0,0 +1,96 @@
// https://codeforces.com/contest/1405/problem/D
#include <bits/stdc++.h>
using namespace std;
using vi = vector<int>;
const int MAXN = 1e5 + 10;
int n, a, b, da, db, distAtoB;
int dist[MAXN];
void dfs(int x, int p, vector<vi> &g)
{
for (auto n : g[x])
{
if (n != p)
{
dist[n] = dist[x] + 1;
dfs(n, x, g);
}
}
}
pair<int, int> farthest(int x)
{
int maxD = INT_MIN, v = -1;
for (int i = 1; i <= n; i++)
{
if (dist[i] > maxD)
{
maxD = dist[i];
v = i;
}
}
return {v, maxD};
}
int diameter(vector<vi> &g)
{
dist[a] = 0;
dfs(a, -1, g);
auto [v, d] = farthest(1);
distAtoB = dist[b];
dist[v] = 0;
dfs(v, -1, g);
auto [_, diam] = farthest(v);
return diam;
}
void solve()
{
cin >> n >> a >> b >> da >> db;
vector<vi> g(n + 1);
for (int i = 1; i <= n - 1; i++)
{
int u, v;
cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
int diam = diameter(g);
if (2 * da >= diam || da >= distAtoB)
{
cout << "Delegado" << endl;
return;
}
db = min(db, diam);
if (db > 2 * da)
{
cout << "Noivo" << endl;
return;
}
cout << "Delegado" << endl;
return;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int testCases = 1;
cin >> testCases;
for (int t = 1; t <= testCases; t++)
{
// cout << "Case #" << t << ": ";
solve();
}
return 0;
}

View File

@@ -0,0 +1,49 @@
from collections import deque
t = int(input())
for _ in range(t):
n, a, b, da, db = map(int, input().split())
adj = [[] for _ in range(n + 1)]
for _ in range(n - 1):
u, v = map(int, input().split())
adj[u].append(v)
adj[v].append(u)
if 2 * da >= db:
print("Alice")
continue
def bfs(start):
dist = [-1] * (n + 1)
dist[start] = 0
q = deque([start])
furthest_node = start
max_d = 0
while q:
u = q.popleft()
for v in adj[u]:
if dist[v] == -1:
dist[v] = dist[u] + 1
q.append(v)
if dist[v] > max_d:
max_d = dist[v]
furthest_node = v
return dist, furthest_node, max_d
dist_from_a, furthest_from_a, _ = bfs(a)
if dist_from_a[b] <= da:
print("Alice")
continue
_, _, diameter = bfs(furthest_from_a)
if diameter <= 2 * da:
print("Alice")
else:
print("Bob")

View File

@@ -0,0 +1,26 @@
#include "testlib.h"
#include <string>
using namespace std;
const string YES = "Delegado";
const string NO = "Noivo";
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,83 @@
#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;
const int MIN_N = 0;
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 x, int y) {
ostringstream oss;
oss << x << " " << y << endl;
return oss.str();
}
vector<string> generate_sample_tests() {
vector<string> tests;
tests.push_back(output_tc(1, 1));
tests.push_back(output_tc(2, 2));
tests.push_back(output_tc(0, 0));
return tests;
}
vector<string> generate_manual_tests() {
vector<string> tests;
tests.push_back(output_tc(100, 0));
tests.push_back(output_tc(0, 100));
return tests;
}
string rnd_test(int i){
int min_n = MIN_N;
int max_n = MAX_N;
if(i<rnd_test_n / 3){
max_n = 5;
}
else if(i<rnd_test_n / 2){
max_n = 20;
}
int x = rnd.next(min_n, max_n);
int y = rnd.next(min_n, max_n);
return(output_tc(x, y));
}
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(output_tc(100, 100));
}
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;
}

1
pique-pega/src/script.sh Normal file
View File

@@ -0,0 +1 @@
generator

5963
pique-pega/src/testlib.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,70 @@
#include "testlib.h"
#include <vector>
using namespace std;
struct DSU {
vector<int> parent;
DSU(int n) {
parent.resize(n + 1);
for (int i = 1; i <= n; i++) parent[i] = i;
}
int find(int i) {
if (parent[i] == i)
return i;
return parent[i] = find(parent[i]);
}
bool unite(int i, int j) {
int root_i = find(i);
int root_j = find(j);
if (root_i != root_j) {
parent[root_i] = root_j;
return true;
}
return false;
}
};
int main(int argc, char* argv[]) {
registerValidation(argc, argv);
int t = inf.readInt(1, 1e4, "t");
inf.readEoln();
int sum_n = 0;
for (int tc = 1; tc <= t; tc++) {
int n = inf.readInt(2, 1e5, "n");
inf.readSpace();
int a = inf.readInt(1, n, "a");
inf.readSpace();
int b = inf.readInt(1, n, "b");
ensuref(a != b, "a and b must be different");
inf.readSpace();
int da = inf.readInt(1, n - 1, "da");
inf.readSpace();
int db = inf.readInt(1, n - 1, "db");
inf.readEoln();
sum_n += n;
ensuref(sum_n <= 1e5, "Sum of n over all test cases must not exceed 10^5");
DSU dsu(n);
for (int i = 0; i < n - 1; i++) {
int u = inf.readInt(1, n, "u");
inf.readSpace();
int v = inf.readInt(1, n, "v");
inf.readEoln();
ensuref(u != v, "Edge must connect two different vertices");
ensuref(dsu.unite(u, v), "Graph contains a cycle or is disconnected (not a tree)");
}
}
inf.readEof();
return 0;
}

View File

@@ -0,0 +1,25 @@
No grande Arraiá de São João, o aguardado Casamento Caipira virou uma tremenda confusão!
O \textbf{Noivo} entrou em pânico na hora do "sim" e fugiu correndo.
Imediatamente, o \textbf{Delegado} da festa foi acionado pelo pai da noiva para capturar o fujão e arrastá-lo direto para a barraca da Cadeia.
O local da festa possui uma organização bem tradicional: o arraiá é composto por $n$ barracas numeradas de $1$ a $n$, que são conectadas por exatamente $n-1$ corredores de terra batida decorados com bandeirinhas coloridas.
A organização foi feita de tal forma que existe sempre um único caminho simples caminhando pelos corredores entre quaisquer duas barracas.
A perseguição começa com o Delegado na barraca $a$, e o Noivo escondido na barraca $b$. Eles correm em turnos alternados, e o \textbf{Delegado dá o primeiro pique de corrida}.
\begin{itemize}
\item No seu turno, o \textbf{Delegado} pode correr por até $d_a$ corredores de bandeirinhas para tentar encurralar o fujão.
\item Na sua vez, o \textbf{Noivo} pode disparar por até $d_b$ corredores para tentar se afastar da autoridade.
\end{itemize}
A distância entre duas barracas é o número de corredores no único caminho entre elas.
No desespero (ou para comer uma paçoca), ambos podem optar por não correr e permanecer na mesma barraca durante o seu turno.
O movimento é focado apenas no destino: eles cruzam os corredores sem parar nas barracas intermediárias.
O Delegado vence se, em até $10^{100}$ turnos, conseguir chegar na \textbf{mesma barraca} que o Noivo, efetuando a prisão.
Caso contrário, se o Noivo conseguir sambar pelo arraiá e despistar o Delegado a noite inteira, o Noivo vence, e continua solteiro.
Sua tarefa é determinar quem sairá vencedor dessa confusão junina, assumindo que tanto o Delegado quanto o Noivo corram e se escondam de maneira absolutamente ótima.
Para cada caso de teste, imprima uma única linha contendo o vencedor dessa perseguição caipira: \texttt{Delegado} ou \texttt{Noivo}.

View File

@@ -0,0 +1,8 @@
A primeira linha da entrada contém um inteiro $t$ ($1 \le t \le 10^4$), indicando o número de casos de teste.
A primeira linha de cada caso de teste contém cinco inteiros: $n, a, b, d_a, d_b$ ($2 \le n \le 10^5$, $1 \le a, b \le n$, $a \neq b$, $1 \le d_a, d_b \le n-1$), representando o número de barracas no arraiá, a barraca inicial do Delegado, a barraca inicial do Noivo, o fôlego máximo de corrida do Delegado e o fôlego máximo de fuga do Noivo, respectivamente.
As próximas $n-1$ linhas descrevem os corredores do arraiá.
Cada linha contém dois inteiros $u$ e $v$ ($1 \le u, v \le n, u \neq v$), indicando um corredor direto de bandeirinhas ligando as barracas $u$ e $v$.
É garantido que a soma de $n$ em todos os casos de teste não excede $10^5$.

View File

@@ -0,0 +1 @@
Problema adaptado de \href{https://codeforces.com/contest/1405/problem/D}{Codeforces Round 668 (Div. 2, Problem D)}.

View File

@@ -0,0 +1 @@
Para cada caso de teste, imprima uma única linha contendo o vencedor dessa perseguição caipira: \texttt{Delegado} ou \texttt{Noivo}.

View File

View File

@@ -0,0 +1,20 @@
O problema pode ser modelado como um jogo de perseguição em um grafo acíclico conectado, uma árvore. A vitória do Delegado é garantida de forma determinística se, e somente se, pelo menos uma das três propriedades estruturais abaixo for satisfeita. Caso contrário, a topologia da árvore garante ao Noivo uma estratégia de evasão infinita.
\begin{enumerate}
\item \textbf{Captura no Primeiro Turno:} Se a distância no grafo entre os vértices iniciais for $dist(a, b) \le d_a$, o Delegado alcança o Noivo imediatamente na sua primeira jogada. Essa distância pode ser calculada em $O(N)$ executando uma Busca em Largura (BFS) ou Busca em Profundidade (DFS) a partir do vértice $a$.
\item \textbf{Cobertura do Diâmetro da Árvore:} O Delegado vence se o diâmetro da árvore, o caminho mais longo entre quaisquer dois vertíces, for $D \le 2 \cdot d_a$.
\begin{itemize}
\item \textbf{Prova:} Em uma árvore de diâmetro $D$, o raio a partir de seu centro absoluto é $\lceil D/2 \rceil$. Se $D \le 2 \cdot d_a$, o Delegado pode simplesmente mover-se em direção ao vértice central da árvore. A partir desse centro, a distância máxima para qualquer outro vértice do grafo será $\le d_a$. Assim, o Delegado passa a cobrir todos os vértices possíveis em um único turno, não deixando zonas seguras para o Noivo.
\item \textbf{Cálculo:} O diâmetro pode ser encontrado linearmente em $O(N)$ usando duas execuções de BFS ou DFS: a primeira partindo de um nó arbitrário para encontrar o nó $u$ mais distante, e a segunda partindo de $u$ para encontrar o nó $v$ mais distante. A distância $dist(u, v)$ será o diâmetro $D$.
\end{itemize}
\item \textbf{Dominância de Raio de Ação:} O Delegado vence se a sua capacidade de movimento anular o potencial de salto do Noivo, o que ocorre estritamente quando $2 \cdot d_a \ge d_b$.
\begin{itemize}
\item \textbf{Prova:} Para que o Noivo consiga escapar de um cerco ao ser encurralado em uma extremidade da árvore, ele precisaria ser capaz de "pular por cima" da zona de controle do Delegado sem aterrissar dentro dela. Como o Delegado controla um raio de $d_a$ ao seu redor, o diâmetro da sua zona de ameaça é $2 \cdot d_a$. Para cruzar essa zona com segurança e ainda ganhar distância, o Noivo precisaria de um salto estritamente maior que a zona de perigo, ou seja, $d_b > 2 \cdot d_a$.
Se essa condição de salto falha, o Delegado pode gradualmente empurrar o Noivo para uma folha da árvore e capturá-lo, reduzindo a distância entre eles a cada turno.
\end{itemize}
\end{enumerate}
Se nenhuma dessas três condições for satisfeita ($dist(a, b) > d_a$, $D > 2 \cdot d_a$ e $d_b > 2 \cdot d_a$), o Noivo sempre terá espaço topológico para manter uma distância de segurança superior a $d_a$ após o seu turno, configurando um jogo infinito.
A complexidade de tempo total para verificar todas as condições e decidir o vencedor é $O(N)$.