Apr 10, 2025
When we are solving network flow problems in competitive programming, one common difficulty revolves around building a flow graph that represents the problem. This blog post summarizes a few common types of graphs in various problems.
Unfortunately, the complexity of network flow on certain types of graphs is rather complicated. While there are some common-sense guidelines (e.g. Dinic runs \(O(\sqrt{n}m)\) on bipartite-matching graphs), in the timeframe of a contest it is often difficult to figure out concretely which algorithm is the best to use.
Therefore, I recommend trying through every algorithm on a code reference until finding one that does not TLE. I carry two (Dinic and ISAP) in my reference, and I have never had a problem that TLE'ed both yet.
Some problems come with a graph and beg you to use network flow. These problems are generally not very interesting but still good to practice as the first network flow problem.
Link: https://codeforces.com/contest/653/problem/D
Niwel is a little golden bear. As everyone knows, bears live in forests, but Niwel got tired of seeing all the trees so he decided to move to the city.
In the city, Niwel took on a job managing bears to deliver goods. The city that he lives in can be represented as a directed graph with \(n\) nodes and \(m\) edges. Each edge has a weight capacity. A delivery consists of a bear carrying weights with their bear hands on a simple path from node \(1\) to node \(n\). The total weight that travels across a particular edge must not exceed the weight capacity of that edge.
Niwel has exactly \(x\) bears. In the interest of fairness, no bear can rest, and the weight that each bear carries must be exactly the same. However, each bear may take different paths if they like.
Niwel would like to determine the maximum amount of weight he can deliver (it is the sum of weights carried by bears). Find the maximum weight.
The first line contains three integers \(n\), \(m\) and \(x\) (\(2 \le n \le 50\), \(1 \le m \le 500\), \(1 \le x \le 100,000\)) — the number of nodes, the number of directed edges and the number of bears, respectively.
Each of the following \(m\) lines contains three integers \(a_i\), \(b_i\) and \(c_i\) (\(1 \le a_i, b_i \le n\), \(a_i \neq b_i\), \(1 \le c_i \le 1,000,000\)). This represents a directed edge from node \(a_i\) to node \(b_i\) with weight capacity \(c_i\). There are no self loops and no multiple edges from one node to another. More formally, for each \(i\) and \(j\) with \(i \neq j\), it is guaranteed that \(a_i \neq a_j\) or \(b_i \neq b_j\). It is also guaranteed that there is at least one path from node \(1\) to node \(n\).
Print one real value on a single line — the maximum amount of weight Niwel can deliver if he uses exactly \(x\) bears. Your answer will be considered correct if its absolute or relative error does not exceed \(10^{-6}\).
Namely: let us assume that your answer is \(a\), and the answer of the jury is \(b\). The checker program will consider your answer correct if \(\frac{|a-b|}{\max(1,|b|)} \le 10^{-6}\).
In the first sample, Niwel has three bears. Two bears can choose the path \[ 1 \to 2 \to 4, \] while one bear can choose the path \[ 1 \to 3 \to 4. \] Even though the bear that goes on the path \(1 \to 3 \to 4\) can carry one unit of weight, in the interest of fairness, he is restricted to carrying \(0.5\) units of weight. Thus, the total weight is \(1.5\) units overall. Note that even though Niwel can deliver more weight with just \(2\) bears, he must use exactly \(3\) bears on this day.
IndiaHacks 2016 - Online Edition (Div. 1 + Div. 2)
Simply binary search the answer and run max flow to see if the maximum flow can be achieved.
One of the motivating problems of network flow is probably the matching problem on a bipartite graph. Formally, given a bipartite graph \(G=(U,V,E)\) where edges only exist between nodes in \(U\) and \(V\), the goal is to identify the maximum matching — the largest subset of edges without shared endpoints.
The key method we will be using in this blog is to build a flow graph that translates this problem to a flow graph — that means every solution to the problem corresponds to a flow solution in the graph, and every flow solution corresponds to a solution to the problem.
For instance, let us consider this flow graph for the bipartite matching problem:
Now let us try to transform some matching solution to a flow solution on this graph. Assuming some matching \((u_i, v_j)\) is in the matching solution, we can create a flow path of capacity 1 that goes through \(s\) – \(u_i\) – \(v_j\) – \(t\). Since no node in the matching solution can be used twice, we are sure that the flow path is always valid, and the maximum matching solution indeed corresponds to a maximum flow solution.
On the other hand, let us try to transform some flow solution to a matching solution. Since every flow path in this graph must be of form \(s\) – \(u_i\) – \(v_j\) – \(t\), we can match \((u_i, v_j)\) for every flow path, and we are done.
Once we establish a one-to-one relation between these two kinds of solutions, we are sure that our flow graph is an accurate representation of the original problem, and we can proceed to code it out.
A common issue with beginners seems to be performing minor tweaks on the graph, so try out this problem that is a minor variation of the same idea.
Link: https://codeforces.com/gym/101981/problem/I
There are \(n\) heroes and \(m\) monsters living on an island. The monsters have become very vicious recently, so the heroes have decided to reduce their numbers. However, the \(i\)-th hero can only kill one monster from the set \(M_i\). Joe, the strategist, has \(k\) bottles of magic potion, each of which can buff one hero's power, allowing him to kill one additional monster. Since the potion is very powerful, a hero can only take at most one bottle of potion.
Please help Joe determine the maximum number of monsters that can be killed by the heroes if he uses the optimal strategy.
The first line contains three integers \(n\), \(m\), \(k\) (\(1 \leq n, m, k \leq 500\)) — the number of heroes, the number of monsters, and the number of bottles of potion.
Each of the next \(n\) lines contains one integer \(t_i\), the size of \(M_i\), followed by \(t_i\) integers \(M_{i,j}\) (\(1 \leq j \leq t_i\)), the indices (1-based) of monsters that can be killed by the \(i\)-th hero (\(1 \leq t_i \leq m\), \(1 \leq M_{i,j} \leq m\)).
Print the maximum number of monsters that can be killed by the heroes.
2018 ACM-ICPC Asia Nanjing Regional Programming Contest
Observe that the only change in this problem is that we now have potions that allow heroes to match one more monster. In other words, a potion allows a hero to carry one point more flow.
Therefore, we add a potion node \(p\) to the original graph. We add an edge from \(s\) to \(p\) with capacity \(k\) (using at most \(k\) potions overall). We then add an edge from \(p\) to every \(u_i\) with capacity \(1\) (using at most one potion on \(u_i\)).
It is easy to see that the flow solution corresponds to the solution to the problem.
Obviously, with the same graph we can also solve weighted bipartite matching, using min-cost network flow.
One enlightening detail here is that, in general, the cost can be negative in these min-cost flow graphs. Otherwise, the graph works exactly as we have seen before.
Side note 1: A minor caveat is that we usually do not want negative cycles to appear as those cycles complicate things and need to be pre-processed. However, most graphs we see today will be DAGs, so we don't have to worry about it too much.
Side note 2: Equivalent algorithmic solutions also exist for bipartite matching, most notably Hopcroft-Karp and Kuhn-Munkres.
Implicitly, a minimum cut solution divides a graph into two parts: a source set connected from the source and a sink set connected to the sink. Therefore, every node is either with the source or with the sink. When building the graph using the concept of the cut, we usually want to model the decision of the problem in line with this concept: when the node is with the source, it means we made some decision; when the node is with the sink, it means we made some other decision.
Now this statement looks very abstract, so let us consider a concrete problem to illustrate the point. I call this the lightbulb problem, although I cannot exactly find a source for it. The problem goes like this:
There are \(n\) lightbulbs. Each lightbulb can either be on or off. To keep the \(i\)-th one on you need to pay \(a_i\); to keep it off you need to pay \(b_i\). There is also a list of \(m\) requirements \((x_j,y_j,c_j)\) — if the \(x_j\) lightbulb is on but the \(y_j\) lightbulb is off, you need to pay \(c_j\). Find the minimum cost.
Now let us build a graph for this problem. First, we add a source \(s\), a sink \(t\), and a node \(u_i\) for every lightbulb. For each lightbulb we have a decision to make — turning it on or off. Let us say that keeping it off corresponds to the node being with the source in the cut, and turning it on corresponds to the node being with the sink in the cut. We add edges according to this model.
We now show that a cut solution corresponds to a lightbulb solution. Observe that every node is either with the source or with the sink in the cut. If the node is with the source, we turn it off (thus paying \(b_i\) cutting off the type-2 edge). If the node is with the sink, we turn it on (thus paying \(a_i\) cutting off the type-1 edge). If some \(x_j\) is with the sink and \(y_j\) is with the source, we pay \(c_j\) to satisfy the requirement. Therefore, the cut solution translates to the lightbulb solution, and vise-versa.
This sort of modeling-decision-with-cut has many flavors. I will quickly showcase a few below.
Link: https://www.luogu.com.cn/problem/P2762
Professor W is planning a series of space flights for the National Space Center. Each flight can perform a series of commercial experiments to generate profit. A set of potential experiments \( E = \{E_1, E_2, \dots, E_m\} \) has been identified, along with a set of instruments \( I = \{I_1, I_2, \dots, I_n\} \) required for these experiments. Each experiment \( E_j \) requires a subset of instruments \( R_j \subseteq I \).
The cost of configuring instrument \( I_k \) is \( c_k \) dollars. The sponsor of experiment \( E_j \) has agreed to pay \( p_j \) dollars for the experiment results. Professor W's task is to develop an efficient algorithm that selects which experiments to perform and which instruments to configure during one space flight in order to maximize the net profit. Here, the net profit is defined as the difference between total revenue from the experiments performed and the total cost of configuring the instruments.
Given the details about the experiments and instrument configurations, write a program to determine the experiment plan that maximizes net profit.
The first line contains two positive integers \( m \) and \( n \) \( (1 \leq n, m \leq 50) \), where \( m \) is the number of experiments and \( n \) is the number of instruments. The next \( m \) lines describe the experiments. Each line begins with an integer representing the payment agreed upon by the experiment's sponsor, followed by the indices of the instruments required for that experiment. The last line contains \( n \) integers, representing the configuration costs for each instrument.
The first line contains the indices of the selected experiments.
The second line contains the indices of the instruments to configure.
The last line contains the maximum net profit.
24 Problems of Network Flow, Luogu
Add a node for every \(E_i\) and a node for every \(I_i\). Let us say that if \(E_i\) is with the source then we carry out the experiment, otherwise we don't. Similarly, if \(I_i\) is with the source then we buy the equipment, otherwise we don't.
Link: https://www.luogu.com.cn/problem/P4313
Choosing between majoring in Arts or Sciences is a tough decision! (Although those who see this problem probably have never struggled with it.)
Student P's class is deciding between Arts and Sciences. His class can be represented by an \(n \times m\) grid, where each cell corresponds to a student's seat. Each student must choose either Arts or Sciences, with the following satisfaction values assigned based on their choice:
Student P wants to know how to choose subjects for everyone in the class so that the total satisfaction value is maximized. Determine this maximum possible value.
The first line contains two positive integers \(n\) and \(m\).
Output a single integer representing the maximum possible total satisfaction.
In the explanation, "1" represents choosing Arts, and "0" represents choosing Sciences. An optimal choice arrangement is:
\(n, m \leq 100\)
All input values are \(\leq 500\).
24 Problems of Network Flow, Luogu
This is similar to the lightbulb problem. The difference is that, instead of paying for two different choices, now we pay an opportunity cost if (at most) 5 people's interests are different.
We can use the same analysis. Let us say that if a node \(c_{i,j}\) is with the source, the student choose art. Otherwise, they choose science.
Sometimes we can use the concept of a bipartite graph to help out:
Link: https://www.luogu.com.cn/problem/P2774
You are given an \(m \times n\) grid where each cell contains a positive integer. The task is to select numbers from the grid so that no two selected numbers are in adjacent cells (two cells are adjacent if they share a common side), and the sum of the selected numbers is maximized. Calculate this maximum sum.
The first line contains two integers separated by a space, representing the number of rows \(m\) and columns \(n\) of the grid.
Each of the next \(m\) lines contains \(n\) integers. The \(j\)-th integer in the \((i+1)\)-th line represents the number \(a_{i,j}\) in the cell at row \(i\) and column \(j\).
Output a single integer representing the maximum achievable sum.
For \(100\%\) of the data: \(1 \leq n, m \leq 100\), and \(1 \leq a_{i,j} \leq 10^5\).
24 Problems of Network Flow, Luogu
Observe that the difference between this problem and the lightbulb one is that we cannot both pick squares at the same time. To counter this, 2-color the grid, and the rest is the same as the lightbulb.
Specifically, for the white cells, we say that we pick it if it is with the source; for the black cells, we say that we pick it if it is with the sink. We add a node \(c_{i,j}\) for every cell, then
Now we are ready for the more obnoxious problems where decisions are not binary. For these problems, a common idea is to build each decision as a path from \(s\) to \(t\), and have the edge being cut (and the subsequent division of nodes on the path) represent a decision.
Link: http://hihocoder.com/problemset/problem/1252
In recent years, many free-to-play games, referred to as Kejin games, have emerged. These games are accessible without charge, but specific items or characters require payment. Examples include Love Live, Kankore, Puzzle & Dragon, Touken Ranbu, and Kakusansei Million Arthur, all of which have gained immense popularity and generate significant revenue daily.
In a Kejin game, your character possesses a skill graph that determines how skills can be acquired. This graph is a directed acyclic graph where vertices represent skills, and edges indicate dependencies: if there is an edge from skill A to skill B, A is a prerequisite for B. In cases where skill S has multiple dependencies, all must be acquired before obtaining S. Furthermore, each edge in the graph is unique, and cyclic dependencies are absent.
Acquiring skills typically involves time and effort, especially for advanced skills deeper in the graph. However, as a player with resources to spare, you can choose to pay money, denoted as "Ke," to bypass certain restrictions. Specifically, money can be used to remove edges from the dependency graph or to acquire skills directly, ignoring existing dependencies.
Given the constraints of time and money, you wish to optimize the balance between them. Each action, be it acquiring a skill through conventional means, removing an edge, or directly purchasing a skill, incurs a cost measured in units of "TA." You seek to determine the minimal cost required to acquire a desired skill S, starting without any initial skills.
The input starts with an integer indicating the number of test cases (no more than 10). Each test case consists of:
The costs for acquiring skills or removing dependencies range up to \(1,000,000\).
For each test case, output a single line containing the minimal cost to acquire the specified skill \(S\).
2015 ACM-ICPC Asia Beijing Regional Contest
For every skill, we build a path from \(s\) to \(t\) that goes through two nodes \(v_{i,1}\) and \(v_{i,2}\), where
Therefore, we add these edges:
And onwards to an even more obnoxious problem in China's national team selection contest.
Link: https://www.luogu.com.cn/problem/P4496
In the year 2323, with rapid technological progress and increasing population pressure on Earth, humanity begins mass migration to Mars. Encouragingly, the first stage of the immigration project is a great success. Currently, \(N\) immigration stations have been established on Mars. The coordinates of the \(i\)-th existing immigration station are \((u_i, v_i)\).
However, a significant challenge emerges: deciding where to build additional immigration stations. Investigations show that \(M\) new immigration stations need to be constructed. It is known that the information flow between the original \(i\)-th station and the new \(j\)-th station is \(A_{i,j}\), and the information flow between the new stations \(j\) and \(k\) is \(B_{j,k}\). It is assumed that transferring one unit of information flow over one unit of distance costs \(1\). Distance is defined as the Manhattan distance. Specifically, the Manhattan distance between two points \((x_1, y_1)\) and \((x_2, y_2)\) is:
\[ \operatorname{ManhattanDist}((x_1, y_1), (x_2, y_2)) = |x_1 - x_2| + |y_1 - y_2| \]
Given the coordinates of the existing \(N\) stations and the matrices \(A\) and \(B\) representing information flows, determine the optimal coordinates for the new \(M\) stations so that the total cost of information transmission is minimized.
The input file names are locate1.in~locate10.in.
The output file names are locate1.out~locate10.out, each corresponding to their respective input files.
The problem only requires submitting output files, so time limit is more lenient.
For input files, \(1\le N, M\le 100\).
China CTSC 2009
First, observe that the x-coordinates and the y-coordinates are independent from each other, so we can consider them separately. For simplicity, let us consider the x-coordinates.
Then, observe that every new station will be built on the x-coordinate of some existing station. Otherwise, we can shift the coordinate of the new station to some existing station nearby and the cost will drop.
Now we are making a decision to pick the x-coordinate for every new station from a list of existing stations. Let us first sort every existing station by their x-coordinate. Then, for every new station \(i\), create a list of nodes \(v_{i,0}, v_{i,1}, \cdots, v_{i,n}\), where a cut between \(v_{i,k}\) and \(v_{i,k+1}\) represents picking the \(k\)-th existing station as the coordinate for the \(i\)-th new station. We can compute the cost of communication between existing stations and the \(i\)-th new station and set it as the edge capacity.
Now we need to process the cost between new stations. The trick is to use a list of edges between \(v_{i,k}\) and \(v_{j,k}\) for every \((i,j,k)\). Observe that if we cut at \(v_{i,k}\) and \(v_{j,l}\) (thickened edges in the figure), every edge from \(v_{j,x}\) to \(v_{i,x}\) with \(x\in[k+1,l]\) will also need to be cut (thickened edges in the figure). Therefore, it suffice to make the capacity of every edge \((X_{k}-X_{k-1})B_{i,j}\), so that it sums over the range and gives us the total cost \((X_{l}-X_{k})B_{i,j}\).
Some problems have you manage certain supplies over days, where you need to meet a variable daily demand by purchasing/refreshing the supplies. In general, we can always create a node for every day and try to do something with min-cost flow, but reality gets very messy very fast...
Link: https://www.luogu.com.cn/problem/P1251
A restaurant needs a varying number of napkins each day over a span of \(N\) consecutive days. Suppose on day \(i\), the restaurant requires \(r_i\) napkins (\(i = 1, 2, \dots, N\)). To meet this demand, the restaurant can:
At the end of each day, the restaurant must decide:
Each day's demand must be satisfied by the napkins washed (from either laundry) plus newly purchased napkins available that day.
Design an algorithm that determines an optimal napkin usage plan over \(N\) days to minimize the total cost. Write a program to compute this minimal total expense.
The input is provided via standard input:
Output a single integer representing the minimal total cost of napkin usage for the restaurant over \(N\) days.
24 Problems of Network Flow, Luogu
Alternatively, the problem can be read as we are supplied with \(r_i\) dirty napkins on day \(i\), and need to pay a debt of \(r_i\) clean napkins that are either bought or come from previous days through washing.
Based on this logic, we add a node \(d_i\) for dirty napkins and \(c_i\) for clean napkins.
The following method of employing chokepoints and bypasses can help with problems that have supplies occupying a specific duration of time.
Link: https://www.luogu.com.cn/problem/P3980
After the successful Olympic bid, Bubu, through tireless efforts, finally becomes the head of the Human Resources department at a company under the Olympic Organizing Committee. Right after taking office, Bubu faces a tough task: recruiting short-term volunteers for a new Olympic project. It has been estimated that the project will last for \(n\) days, and on day \(i\), at least \(a_i\) volunteers are required.
After some investigation, Bubu finds that there are \(m\) types of volunteers available for recruitment. Volunteers of type \(i\) can work continuously from day \(s_i\) to day \(t_i\), with a cost of \(c_i\) per person. To impress everyone at his new job, Bubu wants to recruit enough volunteers at the minimal possible cost — but this isn't his strong suit! Therefore, Bubu comes to you, asking for your help to design an optimal recruitment strategy.
The first line contains two integers \(n, m\), representing the number of days the project will run and the number of volunteer types available for recruitment.
The second line contains \(n\) non-negative integers, representing the minimum number of volunteers required each day.
Each of the next \(m\) lines contains three integers \(s_i, t_i, c_i\), describing the available volunteer types as stated above. Assume that there is an unlimited supply of volunteers for each type. It is guaranteed that a feasible recruitment plan exists.
Output a single integer representing the minimum total cost of your optimal recruitment plan.
China NOI 2008
To start with, let us model each day with a node \(d_i\) and imagine that we connect them in a line from source to sink with capacity \(\infty\) and cost 0. Observe that the maximum flow is \(\infty\) in this graph.
To model the daily needs of \(d_1\), let us change the capacity of the edge that flows to \(d_1\) to \((\infty-a_1)\). Observe that we have created a choke point and the maximum flow is reduced to \((\infty-a_1)\).
We model meeting the demand as restoring the maximum flow to \(\infty\). Towards that end, we model each type of volunteer as a bypass that allows flow to go around the chokepoint. More specifically, for volunteer type \((s,t,c)\), we add an edge from \(d_{s-1}\) to \(d_{t}\) with capacity \(\infty\) and cost \(c\).
Observe that this edge allows us to bypass chokepoints between \(d_{s}\) and \(d_{t}\) by paying \(c\) per unit — the same as hiring a volunteer of that type.
It is also possible to add an edge with a lower bound in the flow graph, essentially "forcing" some amount of flow over that edge in the final solution. Since edges with lower bounds can be translated to edges without them, we don't actually gain extra capabilities, but this method simplifies graph-building down in some problems.
Let us consider a more direct approach to the problem. For every day we still create a node \(c_i\) for clean napkins and \(d_i\) for dirty napkins.
Now let us consider what how do we transform edges with lower bounds to normal edges. To begin with, we add a super source \(s^*\) and a super sink \(t^*\). Observe that to "force" a flow of \(r_i\) from \(c_i\) to \(d_i\) is the same as drawing out \(r_i\) flow from \(c_i\) and injecting \(r_i\) flow into \(d_i\). Therefore, we add an edge from \(c_i\) to \(t^*\) with capacity \(r_i\) and cost 0. Similarly, we add an edge from \(s^*\) to \(d_i\) with capacity \(r_i\) and cost 0.
We want to run our maximum flow with source \(s^*\) and sink \(t^*\) so that every edge going out of \(s^*\) and going into \(t^*\) achieves full capacity, which means that all lower bounds are satisfied. However, we need to fix the original source \(s\) and sink \(t\), since they will have additional incoming/outgoing flows in the original graph. Therefore, we add an edge from \(t\) to \(s\) with capacity \(\infty\) and cost 0, allowing the flow in the original graph that goes out of \(s\) and into \(t\) to cycle back.
Now if we run the min-cost flow on this graph with source \(s^*\) and sink \(t^*\), we simutanously achieve max flow (which means all constraints are satisfied) and min cost (which means we spend the minimum amount of money). You will see that this graph is equivalent to the graph in the original solution.
Observe that this line of methods allows us to add an edge with arbitrary lower bound \(l\) and upper bound \(r\), since such an edge can be decomposed into an edge with "forcing" flow \(l\) and a normal edge with capacity \(r-l\). Now obviously we are going to talk about some obscure Chinese problem that abuses the method to hell.
Link: https://www.luogu.com.cn/problem/P4533
Bingbing has three toys: Pikachu, Winnie-Sun-Wukong, and Barbie. She doesn't know their exact weights (in NOI units), but she knows their approximate ranges:
Table 1: Initial weight range of the toys
Pikachu | Winnie-Sun-Wukong | Barbie | |
---|---|---|---|
Minimum weight | 1 | 2 | 3 |
Maximum weight | 3 | 4 | 5 |
These ranges are too vague; Bingbing wants to narrow them down.
Fortunately, Jiajia has an electronic balance scale. It can indicate not only if both sides weigh the same but also exactly how much heavier (or lighter) one side is compared to the other. The scale is large enough to place multiple toys on either side simultaneously.
Bingbing borrows the scale from Jiajia to determine the precise weights of each toy. To test Bingbing, Jiajia imposes a restriction: each toy can be placed on each side of the scale at most once. For example, if Pikachu was placed on the left side once, it cannot be placed there again. Bingbing agrees and performs two weighings as follows (the numbers show how much heavier the left side is compared to the right):
Pikachu (-1) Winnie-Sun-Wukong
Winnie-Sun-Wukong (1) Barbie
Based on these weighings and Table 1, the exact weights of the three toys can be determined to be precisely 3, 4, and 3 units respectively. Thus, the updated weight ranges are:
Table 2: Exact weight ranges after weighings
Pikachu | Winnie-Sun-Wukong | Barbie | |
---|---|---|---|
Minimum weight | 3 | 4 | 3 |
Maximum weight | 3 | 4 | 3 |
Bingbing will buy many more toys in the future and doesn't want to manually calculate the weights each time. Can you help her write a program to determine the most precise possible lower and upper bounds for each toy's weight?
Note: Each toy is placed on each side at most once throughout all weighings.
Output exactly \(2n\) integers: the \((2i-1)\)-th and \(2i\)-th integers are the refined minimum and maximum integer weights of the \(i\)-th toy. If there is no valid solution (which indicates the scale may be broken or data inconsistent), output only one integer \(-1\).
Example 1 corresponds to the case described in the problem statement.
In Example 2, the three toys have initial weight ranges 1–5, 2–5, and 1–3. After one weighing (toys 1 and 2 on the left, toy 3 on the right, and the left side heavier by 1 unit), the refined ranges become 1–2, 2–3, and 2–3.
China CTSC 2005
We model each measurement as a node \(v_i\). Observe that each toy has exactly one mesaurement \(v_l\) that it appears on the left and one measurement \(v_r\) that it appears on the right. Therefore, we can add an edge from \(v_l\) to \(v_r\) with capacity bound of the initial range.
Now we consider each node \(v_i\). Observe that the incoming flow and the outgoing flow are almost equal, except by the different between the two sides \(D_i\). Therefore, we either add an edge from \(s\) to \(v_i\) or from \(v_i\) to \(t\), depending on which side is heavier, with capacity \(D_i\).
Then, we can add our super source \(s^*\) and super sink \(t^*\), change the graph similar to the solution above, and do the max flow accordingly. If every outgoing edge from \(s^*\) achieves full capacity, we know that we have at least one solution. Otherwise, we have no solutions.
Now we want to find the possible range of each toy. To obtain the upper bound for one toy, observe that we simply need to remove \(s^*\) and \(t^*\), and then run a max flow with source \(v_l\) and sink \(v_r\) on the residual network obtained from the previous max flow, since in the original graph, the only path connecting \(v_l\) and \(v_r\) is exactly the edge represented by the toy, and we need to maximize this flow. To obtain the lower bound, we only need to run a max flow with source \(v_r\) and sink \(v_l\) instead.
To simplify coding, since every outgoing edge from \(s^*\) achieves full capacity, \(s^*\) will not interfere with our max flow, so we don't actually need to remove it. The same goes for \(t^*\).
A list of network flow problems in no particular order:
Thanks ChatGPT for translating all the problems in Chinese to English.
Thanks Prof. Richard Peng for suggesting problems from China NOI/CTSC.