How can I transfer that 'pull' across the network of villages without having to calculate the entire trade route from top to bottom - is there a dynamic way I could do this, such that I could add or take away villages without having to redo the whole calculation from scratch?
First:
1) Give each point on the network a list of adjacent points.
2) Create a temporary array to store exchanges that are "in process"
Then, every cycle:
3) Be aware that step 7 happened on the previous iteration
4) Iterate through villages, checking for matches between what adjacent village want and can give. Any time you have a match, deduct inventory from the give side and add an entry to the temp array indicating who gets what and how much.
5) After step 4 is complete, perform the changes indicted by the temp array
6) Wipe your temp array
7) Assign "how much I want" and "how much I can give" values to each point on the network based on current conditions
The temporary array prevents teleports. You (probably) don't want 1 giving to 2 giving to 3 giving to 4 giving to 5 all on the same turn, simply because you checked those locations in that order.
Note that this process allows networks that are considerably more complicated than the one you have.
Note also that this method does allow individual points to deliver to multiple recipients per iteration if they have enough to deliver. You can add a "how many deliveries have I made?" variable if you want to limit the number of deliveries from each location per turn, for example. Simply check to see if more deliveries are allowable in step 4, then increment it every time a delivery is made, then wipe that data for all locations in step 6.
When computing "how much I can give" remember that each location probably uses the grain too. You might consider also adding a minimum threshold to keep them from giving away grain that they need. If you have 100 people in a location and they each eat 1 grain per turn, you don't want them giving away the last 100 grain and starving to death on that turn just because their neighbor wanted it and they were "capable" of delivering.
Note also that if you iterate exclusively numerically through your connections list, that will create favoritism whereby, for example, if location 1 and 2 both want grain, and location 3 is able to provide it to both of them but only has enough supply for one of the two, location 1 always gets it. You could avoid this in many ways, but for example, you could create a temporary sort by size of demand. Or by adding up the total want, and giving each a fraction of the available give corresponding to how much their want is. For example, if A wants 10 and B wants 15 and C can give 10, then A gets 10/(10+15) * 10 = 4 and B gets 15/(10+15) * 10 = 6.
Note also that this method will result in somewhat delayed propagation. If A and Z are 5 steps away on the network, it will take more than 5 turns for grain from Z to reach A, because the "I need message" will take time to get there, and no individual point knows where its deliveries eventually end up.
Alternately you could set up a LIFO structure, but the above is far simpler and probably does everything you want. You don't really care about pathing in this scenario. It doesn't matter if A gets its grain from D or E, only that the grain propagates through the network and ends up where it's wanted.