• [机房测试]万花筒


    Descrption

    初始 \(m\) 条边,如果 \((u,v)\) 在图中,那么将 \(((u+1)\bmod n+1,(v+1)\bmod n+1)\) 也加入图中。求该图的最小生成树,\(1\leq n\leq 10^9,1\leq m \leq 10^5\)

    Solution

    先考虑暴力求最小生成树,那么一共会有 \(nm\) 条边。但是会发现这些边是有一定规律的。我们将通过 \((u,v)\) 生成的边化为一类。发现如果将这类边全部连起来,会将图化为 \(\gcd(n,abs(u-v))\) 个连通块,连通块内部就不管了,直接减作 \(\gcd(n,abs(u-v))\) 个点。所以可以同时处理一类边的情况。这样就可以做到 \(O(m\log m)\)

    #include<stdio.h>
    #include<algorithm>
    #include<vector>
    using namespace std;
    
    typedef long long ll;
    
    inline int read(){
        int x=0,flag=1; char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')flag=0;c=getchar();}
        while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-48;c=getchar();}
        return flag? x:-x;
    }
    
    struct E{
        int type,w;
        E(int type_=0,int w_=0):type(type_),w(w_){}
        bool operator <(const E &X) const{
            return w<X.w;
        }
    };
    
    vector<E> e;
    int gcd(int x,int y){
        return y? gcd(y,x%y):x;
    }
    
    int main(){
        freopen("kaleidoscope.in","r",stdin);
        freopen("kaleidoscope.out","w",stdout);
        int T=read();
        while(T--){
            ll ans=0; e.clear();
            int n=read(),m=read();
            for(int i=1;i<=m;i++){
                int u=read(),v=read(),w=read();
                e.push_back(E(abs(u-v),w));
            }
            sort(e.begin(),e.end());
            int now=n;
            for(E t:e){
                int x=gcd(t.type,now);
                if(x==now) continue;
                ans+=1ll*(now-x)*t.w;
                now=x; if(x==1) break;
            }
            printf("%lld\n",ans);
        }
    }
    
  • 相关阅读:
    php 工厂模式实例
    nginx多虚拟主机配置
    PHP提高编程效率的方法
    PHP 多态
    锁机制之PHP文件锁
    深入认识javascript中的eval函数(转载)
    PHP&MYSQL 常用的一些性能检测
    寒假作业1:问答题
    软件测试基础知识总结
    七种测试驱动模式
  • 原文地址:https://www.cnblogs.com/wwlwQWQ/p/15422485.html
Copyright © 2020-2023  润新知