Exclude the parent custom post-type posts only

According to the codex for WP_Query, the solution might be to use the post_parent as the id of the top level post. But as there are a whole lotta top level cpts in your case, I think this solution should help you: How to display only top level posts in loop via WP_Query?.

Update:

<?php
    $all = get_posts(array('post_type'=> 'city', 'posts_per_page' => -1));
    $parents = array();
    foreach ($all as $single)
    {
        $kids = get_children($single->ID);  
        if(isset($kids) && !empty($kids) && count($kids) >= 1)
        {
            $parents[] = $single->ID;
        }
    }

    $args = array('post_type' => 'city', 'orderby' => 'name', 'order' => 'ASC', 'posts_per_page' => -1, 'post__not_in' => $parents );

    $city = new WP_Query($args);
    while ($city->have_posts() ) : $city->the_post();
            echo get_the_title()."<br />";
    endwhile;
    wp_reset_postdata();
?>

This is a long cut, but it works. Just make sure you check if the $parents array is not empty before including it in the query.