dp on a functional graph

Revision en7, by htoshiro, 2026-08-15 07:15:15

hello. I have noticed after solving a few problems that there is no documentation on this topic, thus, I have decided to write a short blog. this is my first educational blog so please excuse me if there are errors.

note that this is simply an extension of dp on a tree, so it is strongly recommended you study dp on a tree before reading this blog.

firstly, a functional graph is defined as a directed graph where each vertices has exactly one outgoing edge. a key feature of these graphs is that in a connected functional graph, there is always one and only one cycle present. a proof is attached here. this is crucial to our dp later.

now, let us find an example problem. the problem can be summarized as the following:

Given $$$n$$$ people, person $$$i, 1 \leq i \leq n$$$ can donate $$$a_i$$$ but will not donate if there is a person $$$b_i$$$ which donates. Find the most amount of money that can be donated.

we can model the problem using directed edges from a person to the person they hate, making this a functional graph. we also notice that we can rephrase the problem into: Given a functional graph of $$$N$$$ vertices each with a value $$$a_i$$$ where we cannot take two adjacent vertices, find the maximum value we can achieve,

but there is a problem: we cannot directly run dp on each component since there is a cycle. thus, we will revisit our property earlier that there is only one cycle. the key insight lies in that if we remove one edge present in the cycle, our remaining component will be a tree ($$$n-1$$$ edges, $$$n$$$ vertices, fully connected). let this edge be $$$x \rightarrow y$$$.

note that there is also an edge case where the cycle in the connected component is of length $$$2$$$. in this case, we will obviously not delete the edge as the cycle itself is an edge.

notice that their may be multiple components in our graph, where each component is an individual connected functional graph. thus, we can run this dp for each component and sum up to find the final answer.

I am sure there are easier ways to set up the dp but that is the way which I found most intuitive.

thank you for reading :)

History

 
 
 
 
Revisions
 
 
  Rev. Lang. By When Δ Comment
en20 English htoshiro 2026-08-15 17:10:51 0 (published)
en19 English htoshiro 2026-08-15 17:10:39 214
en18 English htoshiro 2026-08-15 07:59:55 2
en17 English htoshiro 2026-08-15 07:59:00 1 Tiny change: 'j+k \neq 2.\n\nnote ' -> 'j+k \neq 2$.\n\nnote '
en16 English htoshiro 2026-08-15 07:57:47 90
en15 English htoshiro 2026-08-15 07:54:36 5
en14 English htoshiro 2026-08-15 07:53:52 32
en13 English htoshiro 2026-08-15 07:53:28 33 Tiny change: 'r][1] = a_cur+dp[child]' -> 'r][1] = a_{cur}+dp[child]'
en12 English htoshiro 2026-08-15 07:51:29 10
en11 English htoshiro 2026-08-15 07:51:07 36
en10 English htoshiro 2026-08-15 07:50:22 807
en9 English htoshiro 2026-08-15 07:35:01 483
en8 English htoshiro 2026-08-15 07:20:02 0 Tiny change: 'itive.\n\nthank ' -> 'itive.\n\nfor more problems, I \n\nthank '
en7 English htoshiro 2026-08-15 07:15:15 656
en6 English htoshiro 2026-08-15 07:06:20 322
en5 English htoshiro 2026-08-15 07:00:41 2
en4 English htoshiro 2026-08-15 07:00:13 625
en3 English htoshiro 2026-08-15 06:56:11 246
en2 English htoshiro 2026-08-15 06:49:29 754
en1 English htoshiro 2026-08-15 06:42:08 38 Initial revision (saved to drafts)