zoukankan      html  css  js  c++  java
  • 小 X 的道路修建

     

    题目描述

    因为一场不小的地震, Y 省 n 个城市之间的道路都损坏掉了,省长希望小 X 将城市之间的道路重 修一遍。 很多城市之间的地基都被地震破坏导致不能修路了,因此可供修建的道路只有 m 条。因为施工队伍 有限,省长要求用尽量少的道路将所有的城市连通起来,这样施工量就可以尽量少。不过,省长为了表 示自己的公正无私,要求在满足上述条件的情况下,选择一种方案,使得该方案中最贵道路的价格和最 便宜道路的价格的差值尽量小,即使这样的方案会使总价提升很多也没关系。 小 X 现在手忙脚乱,希望你帮帮他。

    输入

    第一行包含两个整数 n; m。 接下来 m 行,每行包含三个整数 a; b; c,表示城市 a; b 之间可以修建一条价格为 c 的无向道路。

    输出

    若存在合法方案,则第一行包含一个整数,表示最贵道路的价格和最便宜道路的价格的最小差值; 否则第一行包含一个整数 −1。

    样例输入

    5 10 1 2 9384 1 3 887 1 4 2778 1 5 6916 2 3 7794 2 4 8336 2 5 5387 3 4 493 3 5 6650 4 5 1422

    样例输出

    1686
    LCT 裸题。
    #pragma GCC optimize("-Ofast")
    #include<bits/stdc++.h>
    #define N 910007
    using namespace std;
    int n,m,ans=INT_MAX,ti;
    void read(int &x){
        static char c; static int b;
        for (b=1,c=getchar();!isdigit(c);c=getchar()) if (c=='-') b=-1;
        for (x=0;isdigit(c);c=getchar()) x=x*10+c-48;
        x*=b;
    }
    struct edge{
        int x,y,z;
        inline bool operator <(const edge& A)const{
           return z<A.z;
        }
    }e[N];
    namespace snow{
    int ch[N][2],fa[N],r[N],mi[N],val[N],id,usd[N];
    bool isroot(int x){
        return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;
    }
    void rev(int x){
        r[x]^=1; swap(ch[x][0],ch[x][1]);
    }
    void pushdown(int x){
        if (!isroot(x)) pushdown(fa[x]);
        if (r[x]) {
            if (ch[x][0]) rev(ch[x][0]);
            if (ch[x][1]) rev(ch[x][1]);
            r[x]=0;
        }
    }
    void pushup(int x){
        mi[x]=val[mi[ch[x][0]]]<val[mi[ch[x][1]]]?mi[ch[x][0]]:mi[ch[x][1]];
        mi[x]=val[mi[x]]<val[x]?mi[x]:x;
    }
    void rotate(int x){
        int y=fa[x],z=fa[y],l,r;
        if (ch[y][0]==x) l=0; else l=1;
        r=l^1;
        if (!isroot(y)) ch[z][ch[z][1]==y]=x;
        fa[x]=z; fa[ch[x][r]]=y; fa[y]=x;
        ch[y][l]=ch[x][r]; ch[x][r]=y;
        pushup(x); pushup(y);
    }
    void splay(int x){
        pushdown(x);
        while (!isroot(x)) {
            int y=fa[x],z=fa[y];
            if (!isroot(y)) {
             if (ch[y][0]==x^ch[z][0]==y) rotate(x);
             else rotate(y);}
            rotate(x);
        }
    }
    void access(int x) {
        int y=0;
        while (x) {
            splay(x);
            ch[x][1]=y;
            pushup(x); 
            y=x;
            x=fa[x];
        }
    }
    void beroot(int x){
        access(x); splay(x); rev(x);
    }
    int root(int x) {
        access(x); splay(x); while (ch[x][0]) x=ch[x][0]; return x; 
    }
    void link(int x,int y){
        beroot(x); fa[x]=y;
    }
    void cut(int x,int y){
       beroot(x);
       access(y); splay(y);
       if (ch[y][0]==x) ch[y][0]=0;
       fa[x]=0;
    } 
    void sol() {
        for (int i=1;i<=m;i++)
         read(e[i].x),read(e[i].y),read(e[i].z);
        sort(e+1,e+m+1); ans=INT_MAX;
        for (int i=0;i<=n;i++) val[i]=INT_MAX;
        for (int i=1;i<=m;i++) val[n+i]=e[i].z;
        int to=1;
        for (int i=1;i<=m;i++) {
            beroot(e[i].x); 
            if (root(e[i].y)!=e[i].x) {
                link(n+i,e[i].x);
                link(n+i,e[i].y); ti++;
            }else {
                id=mi[e[i].y]; usd[id-n]=1;
                cut(id,e[id-n].x);
                cut(id,e[id-n].y);
                link(n+i,e[i].x);
                link(n+i,e[i].y);
            }
           while (usd[to]) to++;
           if (ti==n-1) ans=min(ans,e[i].z-e[to].z);
        }
       printf("%d
    ",ans==INT_MAX?-1:ans);
    }
    }
    signed main () {
        read(n); read(m);
        snow::sol();
    }
  • 相关阅读:
    async await promise写法
    nginx自动启动脚本
    nginx源码编译安装
    PHP源码编译安装
    MySQL修改root密码的多种方法
    PKG_CONFIG_PATH变量 与 ld.so.conf 文件
    confluence5.65+CentOS+mysql安装破解
    nigos core 安装配置
    cacti+CentOS6.5
    Linux+mysql+apache+php
  • 原文地址:https://www.cnblogs.com/rrsb/p/9489583.html
Copyright © 2011-2022 走看看