zoukankan      html  css  js  c++  java
  • bzoj2594

    题解:

    lct维护最小生成树

    首先,先对于每一条边,生成一个点,这个点连接这一条边的两个端点

    点的值为边的权值

    其他点的权值都是0

    那么每一次查找i-j路径上面最小值,就变成查找树上路径点权最小值

    按照最小生成树的方法来生成这一刻lct

    然后先把所有要删去的边删掉,后面再一条一条加上去

    代码:

    #pragma GCC optimize(2)
    #include<bits/stdc++.h>
    using namespace std;
    const int N=2000005;
    int n,m,Q,top,f[N],fa[N],c[N][2],s[N],mx[N],val[N],rev[N];
    struct edge{int u,v,w,id,d;}e[N/2];
    struct que{int f,x,y,ans,id;}q[N/2];
    int operator<(edge a,edge b){return a.u<b.u||(a.u==b.u&&a.v<b.v);}
    int cmp(edge a,edge b){return a.w<b.w;}
    int cmp2(edge a,edge b){return a.id<b.id;}
    int getf(int x){return x==f[x]?x:f[x]=getf(f[x]);}
    int find(int u,int v)
    {
        int l=1,r=m;
        while (l<r)
         {
            int mid=(l+r)/2;
            if (e[mid].u<u||(e[mid].u==u&&e[mid].v<v))l=mid+1;
            else r=mid;
         }
        return l; 
    }
    int isroot(int x){return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;}
    void update(int x)
    {
        int l=c[x][0],r=c[x][1];mx[x]=x;
        if(val[mx[l]]>val[mx[x]])mx[x]=mx[l];
        if(val[mx[r]]>val[mx[x]])mx[x]=mx[r];
    }
    void rotate(int x)
    {
        int y=fa[x],z=fa[y],l,r;
        if(c[y][0]==x)l=0;else l=1;r=l^1;
        if (!isroot(y))
          {
            if (c[z][0]==y)c[z][0]=x;
            else c[z][1]=x;
         }
        fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
        c[y][l]=c[x][r];c[x][r]=y;
        update(y);update(x);
    }
    void pushdown(int x)
    {
        int l=c[x][0],r=c[x][1];
        if (rev[x])
         {
            rev[x]^=1;rev[l]^=1;rev[r]^=1;
            swap(c[x][0],c[x][1]);
         }
    }
    void down(int x)
    {
        if (!isroot(x))down(fa[x]);
        pushdown(x);
    }
    void splay(int x)
    {
        down(x);
        for (int y=fa[x];!isroot(x);rotate(x),y=fa[x])
         if (!isroot(y))rotate((c[y][0]==x)==(c[fa[y]][0]==y)?y:x);
    }
    void access(int x)
    {
        int t=0;
        while (x)
         {
            splay(x);
            c[x][1]=t;
            update(x);
            t=x;x=fa[x];
         }
    }
    void makeroot(int x){access(x);splay(x);rev[x]^=1;}
    void link(int x,int y){makeroot(x);fa[x]=y;}
    void cut(int x,int y){makeroot(x);access(y);splay(y);c[y][0]=fa[x]=0;}
    int query(int x,int y){makeroot(x);access(y);splay(y);return mx[y];}
    int read()
    {
        int x=0;char c;
        for (;c<'0'||c>'9';c=getchar());
        for (;c>='0'&&c<='9';c=getchar())x=x*10+c-48;
        return x;
    }
    int main()
    {
        n=read();m=read();Q=read();
        for (int i=1;i<=n;i++)f[i]=i;
        for (int i=1;i<=m;i++)
         {
            e[i].u=read(),e[i].v=read(),e[i].w=read();
            if (e[i].u>e[i].v)swap(e[i].u,e[i].v);
         }
        sort(e+1,e+m+1,cmp);
        for (int i=1;i<=m;i++)
         {
            e[i].id=i;
            val[n+i]=e[i].w;    
            mx[n+i]=n+i;
         }
        sort(e+1,e+m+1);
        for (int i=1;i<=Q;i++)
         {
            q[i].f=read(),q[i].x=read(),q[i].y=read();
            if (q[i].f==2)
             {
                if(q[i].x>q[i].y)swap(q[i].x,q[i].y);
                int t=find(q[i].x,q[i].y);
                e[t].d=1;q[i].id=e[t].id;
             }
         }
        sort(e+1,e+m+1,cmp2);
        int tot=0;
        for (int i=1;i<=m;i++)
         if (!e[i].d)
          {
             int u=e[i].u,v=e[i].v,x=getf(u),y=getf(v);
            if (x!=y)
             {
                 f[x]=y;
                link(u,i+n);
                link(v,i+n);
             }
          }
        for (int i=Q;i;i--)
         {
             int u=q[i].x,v=q[i].y,k=q[i].id;
            if(q[i].f==1)q[i].ans=val[query(u,v)];
            else
             {
                int t=query(u,v);
                if(e[k].w<val[t])
                 {
                    cut(e[t-n].u,t);cut(e[t-n].v,t);
                    link(u,k+n);link(v,k+n);             
                 }    
             }
         }
        for (int i=1;i<=Q;i++)
         if (q[i].f==1)printf("%d
    ",q[i].ans); 
        return 0;
    }
  • 相关阅读:
    C开发注意事项
    Teamcenter ITK
    Teamcenter SOA开发源码: 打印对象信息
    Teamcenter服务端开发环境配置
    Teamcenter中UID和对象之间相互转化
    Teamcenter 打开数据集
    Teamcenter中SOA调用user service
    63.display:none与visibility:hidden的区别?
    60.为什么要初始化CSS样式
    58.用纯CSS创建一个三角形的原理是什么?
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/8029440.html
Copyright © 2011-2022 走看看