The main goal of the exam is to test your ability to design algorithms. However, this ability is greatly amplified if you *know* about the algorithms and ideas that have been discussed during class.

The point is that most of the algorithms presented in this course have been selected for a very good reason: these algorithms (or at least the ideas behind them) can be used as building blocks for solving numerous problems. Thus, these algorithms are **intellectual tools** that you may use in the design of other algoritms. For instance, exploration of the set of reachable states of a graph is something that one frequently has to do as part of designing a larger algorithm and for this it is useful to know the DFS and BFS algorithms and their key properties. Finding strongly connected components is another example. Numerous problems can be encoded as network flow problems, so knowing the basic algorithms from this area is useful.

Now of course all the students at this university are really smart. Nevertheless, reinventing the brilliant insights of geniuses like Dijkstra, Bellman, Knuth, Tarjan, Hopcroft and Karp during a 3 hours exam will be a major challenge. So you better know about these insights! Knowledge of the algorithms invented by these people will also save you precious time during the exam since you can just refer to it and don't have to spell out the code. For instance, in last years exam Problem 1.1 was equivalent to determining if a directed graph has a single SCC. If you observe this en mention that a linear time algorithm for solving this problem (using 2 applications of DFS) was presented during class you get the maximal score. Another example is problem 3.2, which can simply be solved by encoding the problem as a maximal flow problem and then computing a single augmenting path in the residual graph. As explained during the lectures this problem can be solved in time linear in the size of the graph using the Ford-Fulkerson algorithm. A simple reference to this fact will give you the maximal grade and save you precious time since you don't have to reinvent the wheel.

Knowledge of the complexity of the various algorithms that have been presented is also important. For instance, if you are asked to design a linear time algorithm then it does not make sense to use Dijkstra's algorithm as a subroutine, given that (except for some very special cases) this has a higher complexity.

So although the course objectives are defined purely in terms of abilities ("vaardigheden"), knowledge is really important to achieve these objectives. Students who have not attended the lectures, nor listened to the web-lectures, nor studied the textbook let alone the slides will have a hard time during the exam.

Finally some obvious advice that may help you to pass the exam: (1) answer the questions that are posed, (2) pay attention to the hints. For instance, if a problem is presented under the header ``Divide and conquer'' then it makes sense to look for a divide and conquer algorithm, and if the header says "Network flow" then it makes sense to try to phrase the problem as a maximum flow algorithm, etc (3) often it is better to explain an algorithm textually and via an example then through a page of pseudocode! Always first **think** before you start **coding**!!!!

My main advice: good preparation for the exam requires careful study of the various algorithms that have been presented during class. Also try if you can solve the problems of the exam and retake from 2016 (for the solutions see here and here), the exam from 2017 (for the solution see here), or the exam+solutions from 2018.