Voltar

Link/cut tree - Grafos

0 Curtidas
class splay {
public:
    splay *sons[2], *up, *path_up;
    splay() : up(NULL), path_up(NULL) {
        sons[0] = sons[1] = NULL;
    }

    bool is_r(splay* n) {
        return n == sons[1];
    }
};

void rotate(splay* t, bool to_l) {
    splay* n = t->sons[to_l];       swap(t->path_up, n->path_up);
    t->sons[to_l] = n->sons[!to_l]; if(t->sons[to_l]) t->sons[to_l]->up = t;
    n->up = t->up;                  if(n->up) n->up->sons[n->up->is_r(t)] = n;
    n->sons[!to_l] = t;             t->up = n;
}

void do_splay(splay* n) {
    for(splay* p; (p = n->up) != NULL; )
        if(p->up == NULL)
            rotate(p, p->is_r(n));
        else {
            bool dirp = p->is_r(n), dirg = p->up->is_r(p);
            if(dirp == dirg)
                rotate(p->up, dirg), rotate(p, dirp);
            else
                rotate(p, dirp), rotate(n->up, dirg);
        }
}

struct link_cut {
    splay* vtxs;
    link_cut(int numv) { vtxs = new splay[numv]; }
    ~link_cut() { delete[] vtxs; }

    void access(splay* ov) {
        for(splay *w = ov, *v = ov; w != NULL; v = w, w = w->path_up) {
            do_splay(w);
            if(w->sons[1]) w->sons[1]->path_up = w, w->sons[1]->up = NULL;
            if(w != v) w->sons[1] = v, v->up = w, v->path_up = NULL;
            else w->sons[1] = NULL;
        }
        do_splay(ov);
    }

    splay* find(int v) {
        splay* s = &vtxs[v];
        access(s); while(s->sons[0]) s = s->sons[0]; do_splay(s);
        return s;
    }

    void link(int parent, int son) {
        access(&vtxs[son]); access(&vtxs[parent]);
        assert(vtxs[son].sons[0] == NULL);
        vtxs[son].sons[0] = &vtxs[parent];
        vtxs[parent].up = &vtxs[son];
    }

    void cut(int v) {
        access(&vtxs[v]);
        if(vtxs[v].sons[0]) vtxs[v].sons[0]->up = NULL;
        vtxs[v].sons[0] = NULL;
    }

    int lca(int v, int w) {
        access(&vtxs[v]); access(&vtxs[w]); do_splay(&vtxs[v]);
        if(vtxs[v].path_up == NULL) return v;
        return vtxs[v].path_up - vtxs;
    }
};
Problemas relacionados
  Nome Comentário
Ainda não há nenhum problema relacionado a esse conteúdo

Comentários


Postagens neste fórum só são permitidas para membros com conta ativa. Por favor, efetue login or cadastro para postar.