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();
    }
  • 相关阅读:
    第一节,Django+Xadmin打造上线标准的在线教育平台—创建用户app,在models.py文件生成3张表,用户表、验证码表、轮播图表
    Tensorflow 错误:Unknown command line flag 'f'
    Python 多线程总结
    Git 强制拉取覆盖本地所有文件
    Hive常用函数 傻瓜学习笔记 附完整示例
    Linux 删除指定大小(范围)的文件
    Python 操作 HBase —— Trift Trift2 Happybase 安装使用
    梯度消失 梯度爆炸 梯度偏置 梯度饱和 梯度死亡 文献收藏
    Embedding 文献收藏
    深度学习在CTR预估中的应用 文献收藏
  • 原文地址:https://www.cnblogs.com/rrsb/p/9489583.html
Copyright © 2011-2022 走看看