BZOJ 2594 LCT维护最小生成树

来源:互联网 发布:弗洛伊德算法复杂动画 编辑:程序博客网 时间:2024/04/20 06:37

        调了好久啊,果然不是这错一点就是那错一点……

        我们可以把题目倒过来做,时间倒流,删边变成加边,对于每个查询(u,v),抓出来一条链记录最大值即可

        对于每个加入(u,v),先是找到u,v边上的最大值,如果当前u,v<_max,那么删去最大值那条边,加入u,v

        代码写得很丑,BZOJ上过不了,反正自己测过了~

#include <cstdio>#include <stack>#include <algorithm> using namespace std; const int INF = 1000001;const int MAXN = 100001;const int MAXM = 1000001;const int MAXQ = 100001; void READ(int &x){    char c;    x = 0;    do c = getchar();while (c > '9' || c < '0');    do x = x*10+c-48, c = getchar();while (c >= '0' && c <= '9');} struct Ques{    int oper,u,v,dist,id;}; int n,m,q;int f[2*MAXN];Ques Q[MAXQ];int ans[MAXQ]; struct Edge{    bool flag;    int u,v,dist,id;    bool operator < (const Edge &rhs) const    {        return u < rhs.u || (u == rhs.u && v < rhs.v);    }    Edge(int _u,int _v,int _dist,int _id):u(_u),v(_v),dist(_dist),id(_id){}    Edge(){}}; bool cmp1(Edge A,Edge B){    return A.dist < B.dist;} bool cmp2(Edge A,Edge B){    return A.id < B.id;} Edge Edges[2*MAXM]; struct Node *null;struct Node {    int flag;    int id;    int dist,size;    int _max,maxlocal;    Node *ch[2],*f;    int d(){return f->ch[1] == this ? 1 : 0;}    bool check(){return f != null && (f->ch[0] == this || f->ch[1] == this);}    void setc(Node *c,int d){ch[d] = c, c->f = this;}    Node(int _dist):dist(_dist){size = 1, f = ch[0] = ch[1] = null, flag = false;}    Node(){size = 0, dist = _max = -INF, f = ch[0] = ch[1] = NULL, flag = false;}    void maintain()    {        size = 1+ch[0]->size+ch[1]->size;        maxlocal = id,         _max = dist;        if (ch[0]->_max > _max) maxlocal = ch[0]->maxlocal,_max = ch[0]->_max;        if (ch[1]->_max > _max) maxlocal = ch[1]->maxlocal,_max = ch[1]->_max;    }    void pushdown()    {        if (flag)        {            flag = false;            ch[0]->flag ^= 1, ch[1]->flag ^= 1;            swap(ch[0],ch[1]);        }    }}; Node *p[MAXM*2]; void rotate(Node *p){    Node *x = p->f;    x->pushdown();p->pushdown();    int d = p->d();    if (!x->check()) p->f = x->f;    else x->f->setc(p,x->d());    x->setc(p->ch[d^1],d);    p->setc(x,d^1);    x->maintain();} void Splay(Node *p){    p->pushdown();    while (p->check())    {        Node *x = p->f;        if (!x->check()) rotate(p);        else x->d() == p->d() ? (rotate(x),rotate(p)) : (rotate(p),rotate(p));    }    p->maintain();} void Access(Node *p){    for (Node *q = null; p != null; p = p->f)    {        Splay(p);        p->setc(q,1);        (q = p)->maintain();    }} void MakeRoot(Node *p){    Access(p);Splay(p);    p->flag ^= 1;} void Link(Node *p,Node *q){    MakeRoot(p);    p->f = q;} void Cut(Node *p,Node *q){    MakeRoot(p);    Access(q);Splay(q);    q->ch[0] = p->f = null;    q->maintain();} Node* Query(Node *p,Node *q){    MakeRoot(p);    Access(q);Splay(q);    return q;} int find(int x){    return x == f[x] ? f[x] : f[x] = find(f[x]);} int main(){    null = new Node();    READ(n);READ(m);READ(q);    for (int i=1;i<=2*m;i++) p[i] = new Node(0), p[i]->id = i;    for (int i=1;i<=m;i++)     {        READ(Edges[i].u),READ(Edges[i].v),READ(Edges[i].dist);        if (Edges[i].u > Edges[i].v) swap(Edges[i].u,Edges[i].v);    }    sort(Edges+1,Edges+m+1,cmp1);    for (int i=1;i<=m;i++) Edges[i].id = i;    sort(Edges+1,Edges+m+1);    for (int i=1;i<=q;i++)    {        READ(Q[i].oper),READ(Q[i].u),READ(Q[i].v);        if (Q[i].u > Q[i].v) swap(Q[i].u,Q[i].v);        if (Q[i].oper == 1) continue;        int temp = lower_bound(Edges+1,Edges+m+1,(Edge){Q[i].u,Q[i].v,0,0})-Edges;        Edges[temp].flag = true;        Q[i].dist = Edges[temp].dist;        Q[i].id = Edges[temp].id;    }    sort(Edges+1,Edges+m+1,cmp2);    for (int i=1;i<=2*m;i++) f[i] = i;    int cnt = 0;    for (int i=1;i<=m;i++) if (!Edges[i].flag)    {        int Su = find(Edges[i].u);        int Sv = find(Edges[i].v);        if (Su == Sv) continue;        f[Su] = Sv;        p[i+n]->dist = Edges[i].dist;        Link(p[Edges[i].u],p[i+n]);Link(p[Edges[i].v],p[i+n]);        cnt++;        if (cnt == n-1) break;    }    for (int i=q;i>0;i--)    {        if (Q[i].oper == 1) ans[i] = Query(p[Q[i].u],p[Q[i].v])->_max;        else        {            Node *temp = Query(p[Q[i].u],p[Q[i].v]);            if (Q[i].dist < temp->_max)            {                int point = temp->maxlocal-n;                Cut(p[point+n],p[Edges[point].u]);Cut(p[point+n],p[Edges[point].v]);                point = Q[i].id;                p[point+n]->dist = Q[i].dist;                Link(p[point+n],p[Edges[point].u]);Link(p[point+n],p[Edges[point].v]);            }        }    }    for (int i=1;i<=q;i++) if (Q[i].oper == 1) printf("%d\n",ans[i]);    return 0;}

0 0
原创粉丝点击