#include <iostream>
#include <string>
#include <memory>
#include <vector>

using namespace std;

class City;
using PCity = shared_ptr<City>;
using WCity = weak_ptr<City>;
using UCity = unique_ptr<City>;

class Road;
using PRoad = shared_ptr<Road>;
using WRoad = weak_ptr<Road>;
using URoad = unique_ptr<Road>;


class City {
public:
    City(const std::string& n) : name_(n) { cout << "C-tor city " << name_ << endl; }
    ~City() { cout << "D-tor city " << name_ << endl; }
    void addRoad( PRoad road) { roadsTo_.push_back(road); }
private:
    std::string name_;
    vector<PRoad> roadsTo_;
};


class Road {
public:
    Road(PCity from, PCity to) : from_(from), to_(to) { cout << "C-tor road" << endl; }
    ~Road() { cout << "D-tor road" << endl; }
private:
    WCity from_;
    WCity to_;
};

class Map {
public:
    Map() {}
    PCity addCity(const std::string& name) {
        PCity city = make_shared<City>(name);
        cities_.push_back(city);
        return city;
    }
    void addTwoWayRoad(PCity from, PCity to) {
        addOneWayRoad(from, to);
        addOneWayRoad(to, from);
    }
    void addOneWayRoad(PCity from, PCity to) {
        PRoad r = make_shared<Road>(from, to);
        from->addRoad(r);
    }
private:
    vector<PCity> cities_;
};

int main() {
    Map map;
    PCity a = map.addCity("a");
    PCity b = map.addCity("b");
    map.addTwoWayRoad(a,b);
    return 0;
}
