První řádek vstupu je N = počet uzlů. Doporučuji si po přečtení tohoto čísla inicializovat pole a přidat nové uzly do něj.

Dalších N-1 řádků reprezentuje jednotlivé hrany, v neurčeném pořadí. V každém řádku si propojte dané objekty tak, aby se vám snadno procházely při rekurzivním DFS.

Pro zahájení algoritmu potřebujeme zjistit kořen. To se pravděpodobně nedá udělat o moc lépe, než mít každý uzel na začátku nastavený, že je kořen, a při čtení hran tuto informaci vypínat - pokud nějaký uzel nastavuju do left/right ukazatele jeho rodiče, už to nemůže být kořen. Po přečtení všech hran v poli uzlů zbyde jediný uzel, který tuto informaci má nastavenou na true.

Od tohoto uzlu (kořene) spustíme DFS procházení. Úkolem je najít vzájemně nepodobné podstromy ve stromu a vypsat jejich počet. Definice podobnosti je v zadání, zkráceně:

Podstrom je vždy reprezentován jeho kořenem a jeho potomky. Každý uzel ve stromě je tedy reprezentant takového podstromu. Cílem je najít a spočítat všechny vzájemně nepodobné podstromy. V momentě, kdy porovnávám dva podstromy, musí souhlasit váha na levé hraně a jejich levé podstromy a zároveň váha na pravé hraně a jejich pravé podstromy, případně mohu hrany prohodit (pokud souhlasí levá a pravá hrana, musí souhlasit levý a pravý podstrom).

Jádrem řešení je tedy vygenerovat si pro každý uzel takový identifikátor, který bude odlišný pro nepodobné stromy a stejný pro podobné stromy. Já se vydal cestou reprezentace stringem. Pro každý uzel jsem před svislítko dal certifikát podstromu, do kterého vede větší hrana a za svislítko certifikát podstromu, do kterého vede menší hrana.

Neexistující hrany mají cerifikát inf, listy tedy inf|inf. V example 4 mají uzly 3, 4, 5 tento certifikát:

8(inf|inf)|5(7(inf|inf)|inf)

Vedle si držím seznam dosavadních výsledků, při uzavírání uzlu v DFS si vygeneruji tento certifikát a porovnám ho se všemi dosavadními výsledky. Pokud se se žádným neshoduje, do seznamu ho přidám, jinak ho zahodím.

Na konci vypíšu počet těchto výsledků + 1, protože se mezi ně počítá i prázdný strom (na který ale při procházení v DFS samozřejmě nenarazíte).

Toto řešení získalo 10/12 a pravděpodobně by se dalo urychlit jinou reprezentací a porovnáváním certifikátů.


staci „certifikaty“ sypat do hashmapy, aby se dala v konstatnim case overit pritomnost a je to na 12/12

Pro ilustraci kód v Pythonu:

from sys import stdin
N = int(stdin.readline())
nodes, possible_roots, categories = [[None, None] for i in range(N)], set(range(N)), dict()
for a, b, c, d in (stdin.readline().split() for i in range(N-1)):
    nodes[int(a)][int(b)] = (int(c), int(d)) 
    possible_roots.discard(int(c))
r = lambda i: categories.setdefault(tuple(sorted(
    (r(nodes[i][b][0]), nodes[i][b][1]) for b in (0, 1) if nodes[i][b])), len(categories))
print(r(possible_roots.pop()) + 2)
courses/a4m33pal/zkouska2014_1.txt · Poslední úprava: 2025/01/03 18:29 (upraveno mimo DokuWiki)
Nahoru
chimeric.de = chi`s home Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0