#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional> // reference_wrapper

using namespace std;

class Student;
class Prof;
class Subject;

class Dept
{
    string name;
    vector<Student *> students;
    vector<Prof *> profs;
public:
    Dept( string deptname ) : name(deptname) {}
    void addProf( Prof *p ) { profs.push_back(p); }
    void addStudent( Student *s ) { students.push_back(s); }
};

class Prof
{
    string name;
    Dept *dept;
    vector<Student *> students;
    vector<Subject *> subjects;
public:
    Prof( string name, Dept *dept ) : name(name), dept(dept) { dept->addProf(this); }
    void addStudent( Student *s ) { students.push_back(s); }
    void addSubject( Subject *s ) { subjects.push_back(s); }
};

class Subject
{
    string name;
    Prof *prof;
    vector<Student *> students;
public:
    Subject( string name, Prof *p ) : name(name), prof(p) { p->addSubject(this); }
    void set(string n, Prof *p ) { name = n; prof = p; }
    void addStudent( Student *s ) { students.push_back(s); }
};

class Student
{
    string name;
    Dept *dept;
    Prof *prof;
    vector<Subject *> subjects;
public:
    Student () : name(""), dept(0), prof(0) {}
    Student(string name, Dept *dept, Prof *prof) : name(name), dept(dept), prof(prof)
    { dept->addStudent(this); prof->addStudent(this); }
    void set( string n, Dept *d, Prof *p) { name=n; dept=d; prof=p; }
    void enroll( Subject *s ) { subjects.push_back(s); s->addStudent(this); }
};

int main()
{
    Dept *cep = new Dept("Computer Engineering");
    Prof *shinp = new Prof("Minho Shin", cep);
    Prof *chop = new Prof("Sehyung Cho", cep);
    
    Student *students = new Student[3];
    students[0].set( "Chulsoo Kim", cep, shinp);
    students[1].set( "Miyoung CHoi", cep, chop);
    students[2].set( "Kimoon Ahn", cep, chop);

    vector<Subject*> *subjects = new vector<Subject*>;
    subjects->push_back( new Subject("C++ Programming", shinp) );
    subjects->push_back( new Subject("Java Programming", chop) );
    
    students[0].enroll( subjects->at(0) );
    students[1].enroll( (*subjects)[1] );
    students[2].enroll( subjects->at(1) );
    
    delete cep;
    delete shinp;
    delete chop;
    
    delete[] students;
    delete subjects->at(0);
    delete subjects->at(1);
    delete subjects;
    
    system("read");
    
}