\newcommand{\OPT}{\mathrm{OPT}}

\section{Paarungen (Matchings) in Bäumen}
\begin{tasks}
\item
	\label{1a}
	Ein Baum ist ein kreisfreier, zusammenhängender Graph. Ein Baum besitzt ein
	perfektes Matching genau dann, wenn die Anzahl der Knoten gerade ist und
	jedes Blatt keine Geschwisterknoten hat.

	Die Anzahl der Knoten muss gerade sein, da in einem perfekten Match\-ing jeder
	Knoten mit einem anderen gematcht wird.
	
	Jedes Blatt muss Einzelblatt sein, da der Elternknoten nur mit einem Blatt
	gematcht werden kann.

	Also ist ein perfektes Matching im Baum eindeutig, da jedes Blatt mit seinem
	Elternknoten gematcht werden muss. Diese Kante $uv$ ist sicher im Matching enthalten und alle zu $u$ oder $v$ inzidenten Kanten können aus dem Baum gelöscht werden. So entsteht ein neues Blatt, für das
	die selbe Regel gilt.
	\points{3}
\item
	Der \autoref{alg:treematching} berechnet ein größtes Matching.

	Der Algorithmus ist korrekt, da der Baum $T$ entweder ein perfektes Matching
	enthält und somit ein perfektes Matching berechnet (Siehe \autoref{1a}),
	oder I dont fucking know.

	Die Laufzeit für \algt{Initialize} liegt in $\Oh(V)$, da sich der Baum in linearer Zeit augmentieren lässt und es $\abs{V} - 1$ viele Kanten gibt.

	Die Laufzeit für \algt{MatchaTeeRec} liegt in $\Oh(V)$. Der Algorithmus wird genau
	einmal für jeden Knoten aufgerufen. Wenn eine Kante zum
	Match\-ing hinzugefügt wird, werden die Knoten und Kanten aus dem Baum gelöscht
	die nicht mehr zum Matching hinzugefügt werden können und somit
	nicht mehr bearbeitet werden.

	Also liegt auch \algt{MatchaTee} in $\Oh(V)$.
	\begin{algorithm}
		\centering
		\caption{Größtes Matching in Bäumen}
		\label{alg:treematching}
		\begin{algorithmic}
			\alg{MatchaTee}{$T = \tup{V, E}$} \+ \\
				\com{Den ungerichten Baum zu einem gerichteten Baum mit $parent$ und} \\
				\com{$children$ pro Knoten und einer Wurzel $root$ augmentieren.} \\
				\alg{Initialize}{$T$} \\
				return \alg{MatchaTeeRec}{$T$, $T.root$} \- \\
				\\
			\alg{MatchaTeeRec}{$T$, $r$} \+ \\
				\com{Rekursiv für die Kinder aufrufen} \\
				$m \gets \emptyset$ \\
				foreach $v \in r.children$ do \+ \\
				$m \gets m \cup \text{\alg{MatchaTeeRec}{T, v}}$ \- \\
				\com{Wenn Knoten Blatt ist, dann die Kante zum Elternknoten hinzufügen.} \\
				if $r \neq nil$ and $deg(r) = 1$ then \+ \\
					\com{Die Knoten und inzidente Kanten aus dem Baum entfernen.} \\
					$T \gets T \setminus \set{r.parent, r.parent.children}$ \\
					$m \gets m \cup \set{\set{r, r.parent}}$ \- \\
				return $m$
		\end{algorithmic}
	\end{algorithm}
	\points{5}
\item
	Wenn eine Kante $rv$ zu einem Matching hinzugefügt wird, kann keine zu $v$
	inzidente Kante hinzugefügt werden. Das müssen wir auch bei unserem dynamischen
	Programm beachten.
	\[
		\OPT(r) = \max_{v \in r.children}
		\begin{cases}
		rv + \sum_{i \in v.children} \OPT(i) + \sum_{j \in r.children \setminus v} \OPT(j) \\
		\sum_{k \in r.children} \OPT(k)
		\end{cases}
	\]
	
	Der Algorithmus hält sich an die Eigenschaften eines Matchings, also ist
	er korrekt.

	Der Algorithmus probiert alle Kindknoten von $r$ aus. Geht man mit $r$ im Baum von 
	unten nach oben sind das also höchstens so viele Iterationen wie, Knoten im Baum
	existieren (ohne die Blätter). Also läuft das Dynamische Programm in $\Oh(V)$.

	\points{5}
\end{tasks}
