• [NOI2014]魔法森林


    Description:

    给定一个无向连通图,每条边有两个属性,(a_i,b_i),找一条从1号点到n号点的路径,使路径上的 ({max}a_{i}+maxb_{i}) 最小

    Hint:

    (n=5*10^4,m<=10^5)

    Solution:

    一看到题目就想到最短路,然后发现行不通

    最短路行不通,那就考虑最小生成树

    一个属性显然可以直接做

    但是现在有两个属性

    考虑按边权枚举其中一个属性

    即按 (ai) 排序后每次向图中加入一条边

    同时维护以 (bi) 为边权的最小生成树

    若成环,选择一条 (bi) 较小的边

    每次加边后更新1到n的答案

    维护最小生成树用 (lct) 解决

    #include<bits/stdc++.h>
    using namespace std;
    const int mxn=1e6+5,inf=1e9;
    struct ed {
        int u,v,w,z,id;
    }q[mxn];
    int n,m,tot,mx[mxn],fa[mxn],ch[mxn][2],rev[mxn],st[mxn],val[mxn];
    pair<int ,int > g[mxn];
    map<pair<int ,int >,int > s;
    
    int cmp(ed x,ed y) {
        return x.w<y.w;
    }
    
    inline void checkmi(int &x,int y,int z) {
        if(x>y+z) x=y+z;
    }
    
    namespace lct {
        int isnotrt(int x) {
            return ch[fa[x]][0]==x||ch[fa[x]][1]==x;
        }
        void push_up(int x) {
            mx[x]=x;
            if(val[mx[x]]<val[mx[ch[x][0]]]) mx[x]=mx[ch[x][0]];
            if(val[mx[x]]<val[mx[ch[x][1]]]) mx[x]=mx[ch[x][1]];
        }
        void push_down(int x) {
            if(rev[x]) {
                swap(ch[ch[x][0]][0],ch[ch[x][0]][1]);
                swap(ch[ch[x][1]][0],ch[ch[x][1]][1]);
                rev[ch[x][0]]^=1; rev[ch[x][1]]^=1; rev[x]=0;
            }
        }
        void rotate(int x) {
            int y=fa[x],z=fa[y],tp=ch[y][1]==x;
            if(isnotrt(y)) ch[z][ch[z][1]==y]=x; fa[x]=z;
            ch[y][tp]=ch[x][tp^1],fa[ch[x][tp^1]]=y;
            ch[x][tp^1]=y; fa[y]=x;
            push_up(y),push_up(x);
        }
        void splay(int x) {
            int tp=x,s=0; st[++s]=tp;
            while(isnotrt(tp)) st[++s]=tp=fa[tp];
            while(s) push_down(st[s]),--s;
            while(isnotrt(x)) {
                int y=fa[x],z=fa[y];
                if(isnotrt(y)) 
                    (ch[y][1]==x)^(ch[z][1]==y)?rotate(x):rotate(y);
                rotate(x);
            }
        }
        void access(int x) {
            for(int y=0;x;x=fa[y=x]) 
                splay(x),ch[x][1]=y,push_up(x);
        }
        void makert(int x) {
            access(x); splay(x);
            swap(ch[x][0],ch[x][1]); rev[x]^=1; 
        }
        int findrt(int x) {
            access(x); splay(x);
            while(ch[x][0]) push_down(x),x=ch[x][0];
            splay(x); return x;
        }
        void link(int x,int y) {
            makert(x); fa[x]=y;
        }
        void cut(int x,int y) {
            makert(x); access(y); splay(y);
            fa[x]=ch[y][0]=0; push_up(y);//
        }
        int query(int x,int y) {
            makert(x); access(y); splay(y);
            return mx[y];
        }
    }
    using namespace lct;
    
    int main()
    {
        scanf("%d%d",&n,&m); tot=n; int ans=inf;
        for(int i=1;i<=m;++i) {
            scanf("%d%d%d%d",&q[i].u,&q[i].v,&q[i].w,&q[i].z);
            s[make_pair(q[i].u,q[i].v)]=s[make_pair(q[i].v,q[i].u)]=++tot;
            val[tot]=q[i].z; g[tot]=make_pair(q[i].u,q[i].v);
        }
        sort(q+1,q+m+1,cmp);
        for(int i=1;i<=m;++i) {
            int u=q[i].u,v=q[i].v,w=s[make_pair(u,v)];
            if(findrt(u)!=findrt(v)) 
                link(u,w),link(w,v),mx[w]=w,val[w]=q[i].z;
            else {
                int tp=query(u,v); 
                if(val[tp]>q[i].z) {
                    cut(g[tp].first,tp);
                    cut(g[tp].second,tp);
                    link(u,w); link(v,w);
                    mx[w]=w,val[w]=q[i].z; 
                }
            }
            if(findrt(1)==findrt(n)) checkmi(ans,val[query(1,n)],q[i].w);
        }
        printf("%d",ans==inf?-1:ans);
    }
    
  • 相关阅读:
    mysql数据库给别人访问权限
    linux 5-sort,uniq,tar,split
    linux 4 -awk
    Linux 3 -grep
    linux 基础2-null,cut,wc,head,tail
    linux 基础-变量,shell基本语法
    [ActionScript 3.0] 利用InteractivePNG.as类精确选择识别png图片有像素的区域
    [ActionScript 3.0] 嵌入字体
    [ActionScript 3.0] AS利用ByteArray向PHP发送二进制数据生成图片
    [ActionScript 3.0] AS向php发送二进制数据方法之——在URLRequest中构造HTTP协议发送数据
  • 原文地址:https://www.cnblogs.com/list1/p/10398164.html
Copyright © 2020-2023  润新知