I worked on routing and security in ad-hoc network 10 years ago, when it was still "academic bleeding-edge" (but was a technology already well known to military: I remember one application where they would drop many sensors from a plane and these sensors would manage to communicate with each other and route back data to a central station).
The key thing is that nodes do not know the full network topology, only their first neighbors (ie, in the radio range perimeter). Then, if you want to add efficiency to the routing protocol, nodes can also discover 2nd range neighbors (neighbors of your neighbors), and even 3rd range but then it's not very efficient: you begin to have a lot of traffic only to update each node database when nodes move in and out of radio ranges.
Then, routing has a lot to do with graph theory, only that you just know your neighbors. So based on some logic you decide to send to the neighbor you think is the best, this neighbor does the same, etc. You have to record the path in the packet, to avoid loops, and know which nodes to avoid if the packet gets back to you. There's also a handful of other problems (eg. rogue nodes dropping packets, ...) that makes all of this a poor-performance network.
However, for "static" networks with no moving nodes like sensors, alarm transmitters, ... it works much better since you can learn a lot more about network topology (Xth range neighbors) and just do path discovery when your didn't receive ACK your packet reached destination (in a very dynamic network you would do it almost for each packet).
For sure a lot has changed since 10 years, but by that time, "real-world" application that would Just Work were with static ad-hoc networks, while dynamic ones were just a geek/academic research area with too many shortcomings. So, yes, a static ad-hoc network could be used in a city, but then you still need to get "out" of the city and for that you'll need uplinks to internet, and these can be switched off (not so easily if - say - you use several satellite uplinks).