• bzoj3669(NOI2014)魔法森林


    将边按a排序,一条条加入,若当前的x,y未联通则直接加入这条边,

    否则看当前边的b是否小于x,y,路径上最大的b,小于则拆掉该边,加入当前边。

    显然可以用lct维护,splay维护b的最大值

    把边拆成点权为b的点,点则是点权为0

    Cut时找到改点,splay到根,切掉左右儿子

    Link时加入新点,把x,y newroot,虚父亲指向新点

    //Achen
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<ctime>
    #include<cmath>
    const int N=200000+7; 
    typedef long long LL;
    using namespace std;
    
    template<typename T> void read(T &x) {
        char ch=getchar(); x=0; T f=1;
        while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
        if(ch=='-') f=-1,ch=getchar();
        for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    }
    
    int n,m,ecnt;
    struct edge{
        int x,y,a,b;
        edge(){}
        edge(int x,int y,int a,int b):x(x),y(y),a(a),b(b){} 
        friend bool operator <(const edge&A,const edge&B) {
            return A.a<B.a||(A.a==B.a&&A.b<B.b);
        }
    }e[N];
    
    int tot,ch[N][2],p[N],v[N],bb[N],flip[N];
    #define lc ch[x][0]
    #define rc ch[x][1]
    void update(int x) {v[x]=max(max(bb[x],v[lc]),v[rc]);}
    
    int isroot(int x) {return (ch[p[x]][0]!=x&&ch[p[x]][1]!=x);}
    
    void down(int x) {
        if(!flip[x]) return;
        swap(lc,rc); 
        flip[lc]^=1;
        flip[rc]^=1;
        flip[x]^=1; 
    }
    
    void rotate(int x) {
        int y=p[x],z=p[y],l=(x==ch[y][1]),r=l^1;
        if(!isroot(y)) ch[z][y==ch[z][1]]=x; p[x]=z;
        ch[y][l]=ch[x][r]; p[ch[x][r]]=y;
        ch[x][r]=y; p[y]=x;
        update(y); update(x);
    }
    
    void splay(int x) {
        static int g[N],top=0,tp;
        for(tp=x;!isroot(tp);tp=p[tp]) g[++top]=tp;
        g[++top]=tp;
        while(top) down(g[top--]);
        for(;!isroot(x);rotate(x)) {
            int y=p[x],z=p[y];
            if(!isroot(y))
                ((x==ch[y][1])^(y==ch[z][1]))?rotate(x):rotate(y); 
        } 
    }
    
    void access(int x) {
        for(int t=0;x;x=p[t=x]) {
            splay(x);
            ch[x][1]=t;
            update(x);
        }
    }
    
    int findroot(int x) {
        access(x);
        splay(x);
        while(lc) x=lc;
        return x;
    }
    
    int newroot(int x) {
        access(x);
        splay(x);
        flip[x]^=1;
    }
    
    int qry(int x,int y) {
        newroot(x);
        access(y);
        splay(y);
        return v[y];
    } 
    
    void lik(int x,int y,int w) {
        int z=++tot;
        bb[z]=v[z]=w;
        newroot(x);
        p[x]=z;
        newroot(y);
        p[y]=z;
    }
    
    int find(int x,int y) {
        if(bb[x]==y) return x;
        if(v[lc]==y) return find(lc,y);
        else return find(rc,y);
    }
    
    int cut(int x) {
        splay(x);
        p[ch[x][0]]=0;
        p[ch[x][1]]=0;
    }
    
    void work() {
        int ans=1e9+7;
        sort(e+1,e+m+1);
        for(int i=1;i<=m;i++) {
            int u=e[i].x,v=e[i].y,a=e[i].a,b=e[i].b;
            if(findroot(u)!=findroot(v)) lik(u,v,b);
            else {
                int tp=qry(u,v);
                if(b<tp) {
                    int tpp=find(v,tp);
                    cut(tpp);
                    lik(u,v,b);
                }
            }
            if(findroot(1)==findroot(n)) {
                int tp=qry(1,n);
                ans=min(ans,a+tp);
            }
        } 
        if(ans==1e9+7) ans=-1;
        printf("%d
    ",ans);
    }
    
    void init() {
        read(n); read(m);
        tot=n;
        for(int i=1;i<=m;i++) {
            int x,y,a,b;
            read(x); read(y); read(a); read(b);
            if(x!=y) e[++ecnt]=edge(x,y,a,b); 
        }
        m=ecnt;
    }
    
    int main() {
    #ifdef DEBUG
        freopen(".in","r",stdin);
        freopen(".out","w",stdout);
    #endif
        init();
        work();
        return 0;
    }
    /*
    4 5
    1 2 19 1
    2 3 8 12
    2 4 12 15
    1 3 17 8
    3 4 1 17
    
    3 1
    1 2 1 1
    */
    View Code
  • 相关阅读:
    .net core 实现默认图片
    解决ASP.NET Core部署到IIS,更新项目"另一个程序正在使用此文件,进程无法访问"
    c# 按位与,按位或
    找对象,贤妻良母vs事业型
    基于Redis的分布式锁和Redlock算法
    关于free如何知道要释放内存空间的长度问题(X86篇)
    OpenWrt开发教程(五)shell命令操作json api详解(jshn.sh)
    Linux常见错误码声明
    SDN实验---流表项对网络的影响
    delphi 给TComboBox 添加图标
  • 原文地址:https://www.cnblogs.com/Achenchen/p/8021442.html
Copyright © 2020-2023  润新知