zoukankan      html  css  js  c++  java
  • bzoj 3669

    思想基本同bzoj 2594,但是多了一步

    首先我们发现这时的边有两个属性了,因此我们考虑先去掉其中一者的限制

    我们把所有边按$a$大小排序,然后从小到大加入维护的最小生成树

    每次加边时都按照$b$的大小操作bzoj 2594,然后更新答案即可

    如果始终不联通输出-1

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <stack>
    #include <map>
    using namespace std;
    struct Ques
    {
        int x,y,typ,num;
    }q[1000005];
    struct Edge
    {
        int l,r,v1,v2;
        friend bool operator < (Edge a,Edge b)
        {
            return a.v1==b.v1?a.v2<b.v2:a.v1<b.v1;
        }
    }edge[1000005];
    map <pair<int,int>,int> M;
    int n,m,Q;
    int ch[2000005][2];
    int vis[2000005];
    int maxx[2000005];
    int val[2000005];
    int f[2000005];
    int fl[2000005];
    int ret[2000005];
    void update(int x)
    {
        maxx[x]=val[x];
        if(edge[maxx[ch[x][0]]].v2>edge[maxx[x]].v2)maxx[x]=maxx[ch[x][0]];
        if(edge[maxx[ch[x][1]]].v2>edge[maxx[x]].v2)maxx[x]=maxx[ch[x][1]];
    }
    bool be_root(int x)
    {
        if(ch[f[x]][0]==x||ch[f[x]][1]==x)return 0;
        return 1;
    }
    void pushdown(int x)
    {
        if(fl[x])
        {
            swap(ch[ch[x][0]][0],ch[ch[x][0]][1]);
            swap(ch[ch[x][1]][0],ch[ch[x][1]][1]);
            fl[ch[x][0]]^=1,fl[ch[x][1]]^=1;
            fl[x]=0;
        }
    }
    void repush(int x)
    {
        if(!be_root(x))repush(f[x]);
        pushdown(x);
    }
    void rotate(int x)
    {
       int y=f[x],z=f[y],k=(ch[y][1]==x);
        if(!be_root(y))ch[z][ch[z][1]==y]=x;
        f[x]=z;
        ch[y][k]=ch[x][!k],f[ch[x][!k]]=y;
        ch[x][!k]=y,f[y]=x;
        update(y),update(x);
    }
    void splay(int x)
    {
        repush(x);
        while(!be_root(x)&&x)
        {
            int y=f[x],z=f[y];
            if(!be_root(y)&&y)
            {
                if((ch[y][1]==x)^(ch[z][1]==y))rotate(x);
                else rotate(y);
            }
            rotate(x);
        }
        update(x);
    }
    void access(int x)
    {
        int y=0;
        while(x)
        {
            splay(x);
            ch[x][1]=y;
            update(x);
            y=x,x=f[x];
        }
    }
    void makeroot(int x)
    {
        access(x),splay(x);
        swap(ch[x][0],ch[x][1]),fl[x]^=1;
    }
    void link(int x,int y)
    {
        makeroot(x);
        f[x]=y;
    }
    void split(int x,int y)
    {
        makeroot(x),access(y),splay(y);
    }
    void cut(int x,int y)
    {
        split(x,y),ch[y][0]=f[x]=0,update(y);
    }
    int findf(int x)
    {
        access(x),splay(x),pushdown(x);
        while(ch[x][0])x=ch[x][0],pushdown(x);
        return x;
    }
    inline int read()
    {
        int f=1,x=0;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int main()
    {
        n=read(),m=read();
        for(int i=1;i<=m;i++)
        {
            edge[i].l=read(),edge[i].r=read(),edge[i].v1=read(),edge[i].v2=read();
            if(edge[i].l>edge[i].r)swap(edge[i].l,edge[i].r);
        }
        sort(edge+1,edge+m+1);
        int ans=0x3f3f3f3f;
        for(int i=1;i<=m;i++)val[i+n]=maxx[i+n]=i;
        for(int i=1;i<=m;i++)
        {
            int f1=findf(edge[i].l),f2=findf(edge[i].r);
            if(f1==f2)
            {
                split(edge[i].l,edge[i].r);
                if(edge[maxx[edge[i].r]].v2>edge[i].v2)
                {
                    int t=maxx[edge[i].r];
                    cut(edge[t].l,t+n),cut(edge[t].r,t+n);
                    link(edge[i].l,i+n),link(edge[i].r,i+n);
                }
            }else link(edge[i].l,i+n),link(edge[i].r,i+n);
            int ff1=findf(1),ff2=findf(n);
            if(ff1==ff2)
            {
                split(1,n);
                ans=min(ans,edge[i].v1+edge[maxx[n]].v2);
            }
        }
        if(ans==0x3f3f3f3f)printf("-1
    ");
        else printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    如何在Ubuntu上安装Wine 2.6
    51nod 1012 最小公倍数LCM
    二次urldecode注入
    CTF中的变量覆盖问题
    redis的bind误区
    宽字节注入原理
    PHP靶场-bWAPP环境搭建
    xxe-lab学习
    PHP代码审计之create_function()函数
    SSRF打认证的redis
  • 原文地址:https://www.cnblogs.com/zhangleo/p/11164659.html
Copyright © 2011-2022 走看看