summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--content/geometry/polygon.cpp2
-rw-r--r--content/graph/2sat.cpp4
-rw-r--r--content/graph/bellmannFord.cpp1
-rw-r--r--content/graph/graph.tex208
-rw-r--r--test/graph/2sat.cpp3
-rw-r--r--test/graph/2sat.cpp.awk6
6 files changed, 119 insertions, 105 deletions
diff --git a/content/geometry/polygon.cpp b/content/geometry/polygon.cpp
index 474ce88..ee45539 100644
--- a/content/geometry/polygon.cpp
+++ b/content/geometry/polygon.cpp
@@ -23,7 +23,7 @@ ll windingNumber(pt p, const vector<pt>& poly) {
return res;
}
-// check if point is inside polygon (any polygon)
+// check if p is inside poly (any polygon poly[0] == poly.back())
bool inside(pt p, const vector<pt>& poly) {
bool in = false;
for (int i = 0; i + 1 < ssize(poly); i++) {
diff --git a/content/graph/2sat.cpp b/content/graph/2sat.cpp
index 2b49fc6..b9cfd1c 100644
--- a/content/graph/2sat.cpp
+++ b/content/graph/2sat.cpp
@@ -1,11 +1,9 @@
+constexpr int var(int i) {return i << 1;} // use this!
struct sat2 {
int n; // + scc variablen
vector<int> sol;
-
sat2(int vars) : n(vars*2), adj(n) {}
- static int var(int i) { return i << 1; } // use this!
-
void addImpl(int a, int b) {
adj[a].push_back(b);
adj[1^b].push_back(1^a);
diff --git a/content/graph/bellmannFord.cpp b/content/graph/bellmannFord.cpp
index 09ea1aa..cadcde7 100644
--- a/content/graph/bellmannFord.cpp
+++ b/content/graph/bellmannFord.cpp
@@ -9,7 +9,6 @@ auto bellmannFord(int n, vector<edge>& edges, int start) {
dist[e.to] = dist[e.from] + e.cost;
prev[e.to] = e.from;
}}}
-
for (edge& e : edges) {
if (dist[e.from] != INF &&
dist[e.from] + e.cost < dist[e.to]) {
diff --git a/content/graph/graph.tex b/content/graph/graph.tex
index 7763d79..e46ad07 100644
--- a/content/graph/graph.tex
+++ b/content/graph/graph.tex
@@ -76,15 +76,42 @@
\sourcecode{graph/treeIsomorphism.cpp}
\end{algorithm}
-\subsection{Kürzeste Wege}
+\begin{algorithm}{DFS}
+ \input{graph/dfs}
+\end{algorithm}
-\subsubsection{\textsc{Bellmann-Ford}-Algorithmus}
-\method{bellmanFord}{kürzeste Pfade oder negative Kreise finden}{\abs{V}\*\abs{E}}
-\sourcecode{graph/bellmannFord.cpp}
+\begin{algorithm}{Strongly Connected Components (\textsc{Tarjan})}
+ \begin{methods}
+ \method{scc}{berechnet starke Zusammenhangskomponenten}{\abs{V}+\abs{E}}
+ \end{methods}
+ \textbf{Info:} SCCs sind in umgekehrter topologischer Reihenfolge!
+ \sourcecode{graph/scc.cpp}
+\end{algorithm}
-\subsubsection{Algorithmus von \textsc{Dijkstra}}
-\method{dijkstra}{kürzeste Pfade in Graphen ohne negative Kanten}{\abs{E}\*\log(\abs{V})}
-\sourcecode{graph/dijkstra.cpp}
+\begin{algorithm}{2-SAT}
+ \sourcecode{graph/2sat.cpp}
+\end{algorithm}
+
+\begin{algorithm}{Artikulationspunkte, Brücken und BCC}
+ \begin{methods}
+ \method{find}{berechnet Artikulationspunkte, Brücken und BCC}{\abs{V}+\abs{E}}
+ \end{methods}
+ \textbf{Wichtig:} isolierte Knoten und Brücken sind keine BCC.
+ \sourcecode{graph/articulationPoints.cpp}
+\end{algorithm}
+
+\begin{algorithm}{Cycle Counting}
+ \begin{methods}
+ \method{findBase}{berechnet Basis}{\abs{V}\cdot\abs{E}}
+ \method{count}{zählt Zykel}{2^{\abs{\mathit{base}}}}
+ \end{methods}
+ \begin{itemize}
+ \item jeder Zyklus ist das xor von einträgen in \code{base}.
+ \end{itemize}
+ \sourcecode{graph/cycleCounting.cpp}
+\end{algorithm}
+
+\subsection{Kürzeste Wege}
\subsubsection{\textsc{Floyd-Warshall}-Algorithmus}
\method{floydWarshall}{kürzeste Pfade oder negative Kreise finden}{\abs{V}^3}
@@ -100,6 +127,14 @@ Sei $d_{i\smash{j}}$ die Distanzmatrix von $G$, dann gibt $d_{i\smash{j}}^k$ die
Sei $a_{ij}$ die Adjazenzmatrix von $G$ \textcolor{gray}{(mit $a_{ii} = 1$)}, dann gibt $a_{i\smash{j}}^k$ die Anzahl der Wege von $i$ nach $j$ mit Länge genau \textcolor{gray}{(maximal)} $k$ an mit der Verknüpfung: $c_{i\smash{j}} = a_{i\smash{j}} \otimes b_{i\smash{j}} = \sum a_{ik} \cdot b_{k\smash{j}}$
+\subsubsection{\textsc{Bellmann-Ford}-Algorithmus}
+\method{bellmanFord}{kürzeste Pfade oder negative Kreise finden}{\abs{V}\*\abs{E}}
+\sourcecode{graph/bellmannFord.cpp}
+
+\subsubsection{Algorithmus von \textsc{Dijkstra}}
+\method{dijkstra}{kürzeste Pfade in Graphen ohne negative Kanten}{\abs{E}\*\log(\abs{V})}
+\sourcecode{graph/dijkstra.cpp}
+
\begin{algorithm}{Dynamic Connectivity}
\begin{methods}
\method{Constructor}{erzeugt Baum ($n$ Knoten, $m$ updates)}{n+m}
@@ -108,39 +143,14 @@ Sei $a_{ij}$ die Adjazenzmatrix von $G$ \textcolor{gray}{(mit $a_{ii} = 1$)}, da
\end{methods}
\sourcecode{graph/connect.cpp}
\end{algorithm}
+\clearpage
+
+
-\begin{algorithm}{\textsc{Erd\H{o}s-Gallai}}
- Sei $d_1 \geq \cdots \geq d_{n}$. Es existiert genau dann ein Graph $G$ mit Degreesequence $d$ falls $\sum\limits_{i=1}^{n} d_i$ gerade ist und für $1\leq k \leq n$: $\sum\limits_{i=1}^{k} d_i \leq k\cdot(k-1)+\sum\limits_{i=k+1}^{n} \min(d_i, k)$
- \begin{methods}
- \method{havelHakimi}{findet Graph}{(\abs{V}+\abs{E})\cdot\log(\abs{V})}
- \end{methods}
- \sourcecode{graph/havelHakimi.cpp}
-\end{algorithm}
-\begin{algorithm}{Strongly Connected Components (\textsc{Tarjan})}
- \begin{methods}
- \method{scc}{berechnet starke Zusammenhangskomponenten}{\abs{V}+\abs{E}}
- \end{methods}
- SCCs sind in umgekehrter topologischer Reihenfolge!
- \sourcecode{graph/scc.cpp}
-\end{algorithm}
-\begin{algorithm}{DFS}
- \input{graph/dfs}
-\end{algorithm}
-\begin{algorithm}{Artikulationspunkte, Brücken und BCC}
- \begin{methods}
- \method{find}{berechnet Artikulationspunkte, Brücken und BCC}{\abs{V}+\abs{E}}
- \end{methods}
- \textbf{Wichtig:} isolierte Knoten und Brücken sind keine BCC.
- \sourcecode{graph/articulationPoints.cpp}
-\end{algorithm}
-\vfill\null\columnbreak
-\begin{algorithm}{2-SAT}
- \sourcecode{graph/2sat.cpp}
-\end{algorithm}
\begin{algorithm}{Maximal Cliques}
\begin{methods}
@@ -150,17 +160,35 @@ Sei $a_{ij}$ die Adjazenzmatrix von $G$ \textcolor{gray}{(mit $a_{ii} = 1$)}, da
\sourcecode{graph/bronKerbosch.cpp}
\end{algorithm}
-\begin{algorithm}{Cycle Counting}
+\begin{algorithm}{Maximum Cardinality Bipartite Matching}
+ \label{kuhn}
\begin{methods}
- \method{findBase}{berechnet Basis}{\abs{V}\cdot\abs{E}}
- \method{count}{zählt Zykel}{2^{\abs{\mathit{base}}}}
+ \method{kuhn}{berechnet Matching}{\abs{V}\*\min(ans^2, \abs{E})}
\end{methods}
\begin{itemize}
- \item jeder Zyklus ist das xor von einträgen in \code{base}.
+ \item die ersten [0..l) Knoten in \code{adj} sind die linke Seite des Graphen
\end{itemize}
- \sourcecode{graph/cycleCounting.cpp}
+ \sourcecode{graph/kuhn.cpp}
+ \columnbreak
+ \begin{methods}
+ \method{hopcroft\_karp}{berechnet Matching}{\sqrt{\abs{V}}\*\abs{E}}
+ \end{methods}
+ \sourcecode{graph/hopcroftKarp.cpp}
+\end{algorithm}
+
+\vfill\null
+\columnbreak
+
+\begin{algorithm}{Maximum Weight Bipartite Matching}
+ \begin{methods}
+ \method{match}{berechnet Matching}{\abs{V}^3}
+ \end{methods}
+ \sourcecode{graph/maxWeightBipartiteMatching.cpp}
\end{algorithm}
+\vfill\null
+\columnbreak
+
\begin{algorithm}{Wert des maximalen Matchings}
Fehlerwahrscheinlichkeit: $\left(\frac{m}{MOD}\right)^I$
\sourcecode{graph/matching.cpp}
@@ -173,28 +201,8 @@ Sei $a_{ij}$ die Adjazenzmatrix von $G$ \textcolor{gray}{(mit $a_{ii} = 1$)}, da
\sourcecode{graph/blossom.cpp}
\end{algorithm}
-\begin{algorithm}{Rerooting Template}
- \sourcecode{graph/reroot.cpp}
-\end{algorithm}
-
-\begin{algorithm}{Virtual Trees}
- \sourcecode{graph/virtualTree.cpp}
-\end{algorithm}
-
-\begin{algorithm}{Maximum Cardinality Bipartite Matching}
- \label{kuhn}
- \begin{methods}
- \method{kuhn}{berechnet Matching}{\abs{V}\*\min(ans^2, \abs{E})}
- \end{methods}
- \begin{itemize}
- \item die ersten [0..l) Knoten in \code{adj} sind die linke Seite des Graphen
- \end{itemize}
- \sourcecode{graph/kuhn.cpp}
- \begin{methods}
- \method{hopcroft\_karp}{berechnet Matching}{\sqrt{\abs{V}}\*\abs{E}}
- \end{methods}
- \sourcecode{graph/hopcroftKarp.cpp}
-\end{algorithm}
+\vfill\null
+\columnbreak
\begin{algorithm}{Global Mincut}
\begin{methods}
@@ -205,15 +213,31 @@ Sei $a_{ij}$ die Adjazenzmatrix von $G$ \textcolor{gray}{(mit $a_{ii} = 1$)}, da
\sourcecode{graph/stoerWagner.cpp}
\end{algorithm}
+\begin{algorithm}{Rerooting Template}
+ \sourcecode{graph/reroot.cpp}
+\end{algorithm}
+
+\begin{algorithm}{Virtual Trees}
+ \sourcecode{graph/virtualTree.cpp}
+\end{algorithm}
+
+\begin{algorithm}{\textsc{Erd\H{o}s-Gallai}}
+ Sei $d_1 \geq \cdots \geq d_{n}$. Es existiert genau dann ein Graph $G$ mit Degreesequence $d$ falls $\sum\limits_{i=1}^{n} d_i$ gerade ist und für $1\leq k \leq n$: $\sum\limits_{i=1}^{k} d_i \leq k\cdot(k-1)+\sum\limits_{i=k+1}^{n} \min(d_i, k)$
+ \begin{methods}
+ \method{havelHakimi}{findet Graph}{(\abs{V}+\abs{E})\cdot\log(\abs{V})}
+ \end{methods}
+ \sourcecode{graph/havelHakimi.cpp}
+\end{algorithm}
+
\subsection{Max-Flow}
\optional{
-\subsubsection{Push Relabel \opthint}
-\begin{methods}
- \method{maxFlow}{gut bei sehr dicht besetzten Graphen.}{\abs{V}^2\*\sqrt{\abs{E}}}
- \method{addEdge}{fügt eine \textbf{gerichtete} Kante ein}{1}
-\end{methods}
-\sourcecode{graph/pushRelabel.cpp}
+ \subsubsection{Push Relabel \opthint}
+ \begin{methods}
+ \method{maxFlow}{gut bei sehr dicht besetzten Graphen.}{\abs{V}^2\*\sqrt{\abs{E}}}
+ \method{addEdge}{fügt eine \textbf{gerichtete} Kante ein}{1}
+ \end{methods}
+ \sourcecode{graph/pushRelabel.cpp}
}
\subsubsection{\textsc{Dinitz}'s Algorithm mit Capacity Scaling}
@@ -232,37 +256,27 @@ Sei $a_{ij}$ die Adjazenzmatrix von $G$ \textcolor{gray}{(mit $a_{ii} = 1$)}, da
\columnbreak
\optional{
-\subsubsection{Anwendungen \opthint}
-\begin{itemize}
- \item \textbf{Maximum Edge Disjoint Paths}\newline
- Finde die maximale Anzahl Pfade von $s$ nach $t$, die keine Kante teilen.
- \begin{enumerate}
- \item Setze $s$ als Quelle, $t$ als Senke und die Kapazität jeder Kante auf 1.
- \item Der maximale Fluss entspricht den unterschiedlichen Pfaden ohne gemeinsame Kanten.
- \end{enumerate}
- \item \textbf{Maximum Independent Paths}\newline
- Finde die maximale Anzahl an Pfaden von $s$ nach $t$, die keinen Knoten teilen.
- \begin{enumerate}
- \item Setze $s$ als Quelle, $t$ als Senke und die Kapazität jeder Kante \emph{und jedes Knotens} auf 1.
- \item Der maximale Fluss entspricht den unterschiedlichen Pfaden ohne gemeinsame Knoten.
- \end{enumerate}
- \item \textbf{Min-Cut}\newline
- Der maximale Fluss ist gleich dem minimalen Schnitt.
- Bei Quelle $s$ und Senke $t$, partitioniere in $S$ und $T$.
- Zu $S$ gehören alle Knoten, die im Residualgraphen von $s$ aus erreichbar sind (Rückwärtskanten beachten).
-\end{itemize}
+ \subsubsection{Anwendungen}
+ \begin{itemize}
+ \item \textbf{Maximum Edge Disjoint Paths}\newline
+ Finde die maximale Anzahl Pfade von $s$ nach $t$, die keine Kante teilen.
+ \begin{enumerate}
+ \item Setze $s$ als Quelle, $t$ als Senke und die Kapazität jeder Kante auf 1.
+ \item Der maximale Fluss entspricht den unterschiedlichen Pfaden ohne gemeinsame Kanten.
+ \end{enumerate}
+ \item \textbf{Maximum Independent Paths}\newline
+ Finde die maximale Anzahl an Pfaden von $s$ nach $t$, die keinen Knoten teilen.
+ \begin{enumerate}
+ \item Setze $s$ als Quelle, $t$ als Senke und die Kapazität jeder Kante \emph{und jedes Knotens} auf 1.
+ \item Der maximale Fluss entspricht den unterschiedlichen Pfaden ohne gemeinsame Knoten.
+ \end{enumerate}
+ \item \textbf{Min-Cut}\newline
+ Der maximale Fluss ist gleich dem minimalen Schnitt.
+ Bei Quelle $s$ und Senke $t$, partitioniere in $S$ und $T$.
+ Zu $S$ gehören alle Knoten, die im Residualgraphen von $s$ aus erreichbar sind (Rückwärtskanten beachten).
+ \end{itemize}
}
-\begin{algorithm}{Maximum Weight Bipartite Matching}
- \begin{methods}
- \method{match}{berechnet Matching}{\abs{V}^3}
- \end{methods}
- \sourcecode{graph/maxWeightBipartiteMatching.cpp}
-\end{algorithm}
-\vfill\null
-\columnbreak
-
-
\begin{algorithm}[optional]{TSP}
\begin{methods}
\method{TSP}{berechnet eine Tour}{n^2\*2^n}
diff --git a/test/graph/2sat.cpp b/test/graph/2sat.cpp
index fc3186e..cf37131 100644
--- a/test/graph/2sat.cpp
+++ b/test/graph/2sat.cpp
@@ -1,9 +1,6 @@
#include "../util.h"
#include <graph/scc.cpp>
-#define static vector<vector<int>> adj; static // hacky...
#include <graph/2sat.cpp>
-#undef static
-#undef adj
struct RandomClause {
int a, b;
diff --git a/test/graph/2sat.cpp.awk b/test/graph/2sat.cpp.awk
new file mode 100644
index 0000000..d0215d8
--- /dev/null
+++ b/test/graph/2sat.cpp.awk
@@ -0,0 +1,6 @@
+/scc variablen/ {
+ print;
+ print "\tvector<vector<int>> adj;";
+ next
+}
+{ print }