zoukankan      html  css  js  c++  java
  • BZOJ3714 PA2014Kuglarz(最小生成树)

      每次询问所获得的可以看做是两个前缀和的异或。我们只要知道任意前缀和的异或就可以得到答案了。并且显然地,如果知道了a和b的异或及a和c的异或,也就知道了b和c的异或。所以一次询问可以看做是在两点间连边,所要求的东西就是最小生成树了。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    #define N 2010
    int n,fa[N];
    long long ans=0;
    struct data
    {
        int x,y,z;
        bool operator <(const data&a) const
        {
            return z<a.z;
        }
    }edge[N*N];
    int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj3714.in","r",stdin);
        freopen("bzoj3714.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        n=read();int t=0;
        for (int i=1;i<=n;i++)
            for (int j=i;j<=n;j++)
            t++,edge[t].x=i-1,edge[t].y=j,edge[t].z=read();
        sort(edge+1,edge+t+1);
        for (int i=0;i<=n;i++) fa[i]=i;
        for (int i=1;i<=t;i++)
        if (find(edge[i].x)!=find(edge[i].y)) ans+=edge[i].z,fa[find(edge[i].x)]=find(edge[i].y);
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    RTP 控制协议
    非关系型数据库
    关系型数据库
    处理海量数据
    处理大并发
    C++ 模板偏特化-来自STL的思考
    C++详解new/delete
    二分算法来相会
    计算机网络知识点总结
    C++字符串类型转换
  • 原文地址:https://www.cnblogs.com/Gloid/p/9723734.html
Copyright © 2011-2022 走看看