2018-2019 ACM-ICPC 徐州区域赛

https://codeforces.com/gym/102012

A.Rikka with Minimum Spanning Trees(求最小生成树个数与总权值的乘积)

#include<bits/stdc++.h>

using namespace std;

typedef unsigned long long ull;

const int maxn=100010;
const ull mod=1e9+7;

int m,n,f[maxn];
ull k1,k2;
struct edge
{
    int u,v;
    ull w;
} e[maxn];

int find(int x)
{
    return x==f[x]?x:f[x]=find(f[x]);
}

bool cmp(edge a,edge b)
{
    if (a.w!=b.w)
        return a.w<b.w;
    if (a.u!=b.u)
        return a.u<b.u;
    if (a.v!=b.v)
        return a.v<b.v;
}

ull xorShift128Plus()
{
    ull k3=k1,k4=k2;
    k1=k4;
    k3^=k3<<23;
    k2=k3^k4^(k3>>17)^(k4>>26);
    return k2+k4;
}
void gen()
{
    scanf("%d%d%llu%llu",&n,&m,&k1,&k2);
    for (int i=1; i<=n; i++)
    {
        f[i]=i;
    }
    for (int i=1; i<=m; i++)
    {
        e[i].u=xorShift128Plus()%n+1;
        e[i].v=xorShift128Plus()%n+1;
        e[i].w=xorShift128Plus();
        if (e[i].u>e[i].v)
        {
            swap(e[i].u,e[i].v);
        }
    }
}

void kurskal()
{
    gen();
    sort(e+1,e+1+m,cmp);
    int cnt=0;
    ull cost=0,time=1,res;
    for (int i=1; i<=m; i++)
    {
        int fu=find(e[i].u),fv=find(e[i].v);
        if (fu!=fv)
        {
            res=1;
            f[fu]=fv;
            cost=(cost+e[i].w)%mod;
            cnt++;
            while (i+1<=m&&e[i].u==e[i+1].u&&e[i].v==e[i+1].v&&e[i].w==e[i+1].w)
            {
                i++;
                res++;
            }
            time=time*res%mod;
        }
        if (cnt==n-1)
        {
            break;
        }
    }
    if (cnt==n-1)
    {
        printf("%llu\n",cost%mod*time%mod);
    }
    else
    {
        printf("0\n");
    }
}

int main()
{
    int _;
    scanf("%d",&_);
    while (_--)
    {
        kurskal();
    }
    return 0;
}

  

 

posted @ 2019-08-11 21:23  Snow_in_winer  阅读(933)  评论(0编辑  收藏  举报