Hello everyone! I am your old friend Rikka. Welcome to Xuzhou. This is the first problem, which is a problem about the minimum spanning tree (MST). I promise you all that this should be the easiest problemeasiest problem for most people.

A minimum spanning tree, or minimum weight spanning tree, is a subset of edges from an edge-weighted undirected graph, which forms a tree with the minimum possible total edge weight that connects all the vertices together without any cycles.

In this problem, Rikka wants you to calculate the summation of total edge weights through all MSTs for a given graph, which obviously equals to the product of the total edge weight in an MST and the total number of different MSTs. Note that two spanning trees are different if the sets of their edges are different. In addition, a disconnected graph could have no MSTs, the number of whose different MSTs is zero.

To decrease the size of the input, Rikka provides an edge-weighted undirected graph via a random number generator with given random seeds, denoted by two integers k1​ and k2​. Supposing the number of vertices and edges in the graph are n and m respectively, the following code in C++ tells you how to generate the graph and store the ii-th edge between the vertex u[i] and v[i] with weight w[i] in corresponding arrays. You can use the code directly in your submissions.

unsigned long long k1, k2;

unsigned long long xorShift128Plus() {
unsigned long long k3 = k1, k4 = k2;
k1 = k4;
k3 ^= k3 << ;
k2 = k3 ^ k4 ^ (k3 >> ) ^ (k4 >> );
return k2 + k4;
} int n, m, u[], v[];
unsigned long long w[]; void gen() {
scanf("%d%d%llu%llu", &n, &m, &k1, &k2);
for(int i = ; i <= m; ++i) {
u[i] = xorShift128Plus() % n + ;
v[i] = xorShift128Plus() % n + ;
w[i] = xorShift128Plus();
}
}

Also, to decrease the size of the output, your code should output the answer modulo (109+7).

If you have already learned how to handle that,If you have already learned how to handle that,start your show and omit all the rest of the statement.start your show and omit all the rest of the statement.

To make sure everyone knows how to solve this problem, here Rikka would like to provide for you all an effective practice which can solve the problem and help you all get Accepted!

The first one you need to know is the Kirchhoff's matrix tree theorem. Given an undirected graph G with n vertices excluding all loops, its Laplacian matrix Ln×n​ is defined as (D−A), where D is the degree matrix and A is the adjacency matrix of the graph. More precisely, in the matrix L the entry li,j (i≠j) equals to −m where m is the number of edges between the i-th vertex and the j-th vertex, and Li,i​ equals to the degree of the i-th vertex. Next, construct a matrix L∗ by deleting any row and any column from L, for example, deleting row 1 and column 1. The Kirchhoff's matrix tree theorem shows that the number of spanning trees is exactly the determinant of L∗, which can be computed in polynomial time.

Now let me explain an algorithm that counts the number of MSTs. The algorithm breaks up the Kruskal's algorithm for MST into a series of blocks, each of which consists of a sequence of operations about adding edges in a same weight into a multigraph (where a multigraph is a graph, two vertices of which may be connected by more than one edge) whose vertices are components that have been built through the previous block of operations.

Precisely speaking, let's label the multigraph that has been built after the i-th block of operations as Gi​. Without loss of generality, let's consider the 0-th block which has no operation and let G0​ be an empty graph with n isolated vertices. The i-th block of operations squeezes vertices in Gi−1​ connected by edges in this block into a single vertex. The result is exactly the graph Gi​.

If you know the cardinal principle of Kruskal's algorithm pretty well, you may find that the number of MSTs is the product of the numbers of spanning trees in every component of the graph for each block-defining weight. Actually, the number of edges for a certain weight is fixed in all MSTs, based on the greedy-choice strategy in Kruskal's algorithm. Finally, the Kirchhoff's matrix tree theorem helps you compute the numbers of spanning trees for graphs.

Input

The input contains several test cases, and the first line contains a single integer T (1≤T≤100), the number of test cases.

For each test case, the only line contains four integers n (1≤n≤105), m (m=105), k1 and k2​ (108≤k1,k2≤1012), where k1 and k2​ are chosen randomly except for the sample.

Output

For each test case, output a single line with a single number, the answer modulo (109+7).

Note

Since the generator code is only provided for C++, Rikka strongly suggests you all solve the problem using C or C++ instead of other programming languages.

Sample Input:

1
2 100000 123456789 987654321

Sample Output:

575673759

题意:

给你一个随机函数,其中n为点的数量,m为边的数量,该函数会自动初始化出一张无向无环图,函数如下所示:

typedef unsigned long long ll;
ll k1,k2;
ll xorShift128Plus()
{
ll k3=k1,k4=k2;
k1=k4;
k3^=k3<<;
k2=k3^k4^(k3>>)^(k4>>);
return k2+k4;
}
void gen()
{
scanf("%d%d%llu%llu",&n,&m,&k1,&k2);for(int i=;i<=m;i++)
{
e[i].u=xorShift128Plus()%n+;
e[i].v=xorShift128Plus()%n+;
e[i].w=xorShift128Plus();
}
}

利用如上所示随机函数求出该图所形成的最小生成树个数与该最小生成树总权值的乘积。

思路:

题面很长,很具有干扰性,当时看了很久才发现很多信息其实都是无效的,明白出题人用意后就发现题目很简单。即求最小生成树的个数与该最小生成树总权值的乘积,不过要注意:如果没有最小生成树则输出0;涉及较大数据量的变量要用unsigned long long表示。

#include<bits/stdc++.h>
#define MAX 100000
#define mod 1000000007
using namespace std;
typedef unsigned long long ll;
int n,m,p[MAX+];
struct edge{
int u,v;
ll w;
}e[MAX+];
int find(int r)
{
if(p[r]!=r) p[r]=find(p[r]);
return p[r];
}
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!=a.v)return a.v<b.v;
}
ll k1,k2;
ll xorShift128Plus()
{
ll k3=k1,k4=k2;
k1=k4;
k3^=k3<<;
k2=k3^k4^(k3>>)^(k4>>);
return k2+k4;
}
void gen()
{
scanf("%d%d%llu%llu",&n,&m,&k1,&k2);
for(int i=;i<=n;i++)p[i]=i;
for(int i=;i<=m;i++)
{
e[i].u=xorShift128Plus()%n+;
e[i].v=xorShift128Plus()%n+;
e[i].w=xorShift128Plus();
if(e[i].u>e[i].v)
swap(e[i].u,e[i].v);
}
}
void kurskal()
{
gen();
sort(e+,e+m+,cmp);
int cnt=,i;
ll cost=,time=,res;
for(i=;i<=m;i++)
{
int fu=find(e[i].u),fv=find(e[i].v);
if(fu!=fv)
{
res=;
p[fu]=fv;
cost+=e[i].w;
cnt++;
while(i+<=m&&e[i].u==e[i+].u&&e[i].v==e[i+].v&&e[i].w==e[i+].w)
{
i++;
res++;
}
time=time*res%mod;
cost=cost%mod;
}
if(cnt==n-)break;
}
if(cnt==n-)
printf("%llu\n",cost%mod*time%mod);
else printf("0\n");
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
kurskal();
return ;
}

【2018 ICPC亚洲区域赛徐州站 A】Rikka with Minimum Spanning Trees(求最小生成树个数与总权值的乘积)的更多相关文章

  1. 【2018 ICPC亚洲区域赛南京站 A】Adrien and Austin(博弈)

    题意: 有一排n个石子(注意n可以为0),每次可以取1~K个连续的石子,Adrien先手,Austin后手,若谁不能取则谁输. 思路: (1) n为0时的情况进行特判,后手必胜. (2) 当k=1时, ...

  2. 【2018 ICPC亚洲区域赛沈阳站 L】Tree(思维+dfs)

    Problem Description Consider a un-rooted tree T which is not the biological significance of tree or ...

  3. 2019~2020icpc亚洲区域赛徐州站H. Yuuki and a problem

    2019~2020icpc亚洲区域赛徐州站H. Yuuki and a problem 题意: 给定一个长度为\(n\)的序列,有两种操作: 1:单点修改. 2:查询区间\([L,R]\)范围内所有子 ...

  4. 2014ACM/ICPC亚洲区域赛牡丹江站汇总

    球队内线我也总水平,这所学校得到了前所未有的8地方,因为只有两个少年队.因此,我们13并且可以被分配到的地方,因为13和非常大的数目.据领队谁oj在之上a谁去让更多的冠军.我和tyh,sxk,doub ...

  5. 2014ACM/ICPC亚洲区域赛牡丹江站现场赛-A ( ZOJ 3819 ) Average Score

    Average Score Time Limit: 2 Seconds      Memory Limit: 65536 KB Bob is a freshman in Marjar Universi ...

  6. 2014ACM/ICPC亚洲区域赛牡丹江站现场赛-K ( ZOJ 3829 ) Known Notation

    Known Notation Time Limit: 2 Seconds      Memory Limit: 65536 KB Do you know reverse Polish notation ...

  7. 【2013 ICPC亚洲区域赛成都站 F】Fibonacci Tree(最小生成树+思维)

    Problem Description Coach Pang is interested in Fibonacci numbers while Uncle Yang wants him to do s ...

  8. 【2017 ICPC亚洲区域赛沈阳站 K】Rabbits(思维)

    Problem Description Here N (N ≥ 3) rabbits are playing by the river. They are playing on a number li ...

  9. 2014ACM/ICPC亚洲区域赛牡丹江站现场赛-I ( ZOJ 3827 ) Information Entropy

    Information Entropy Time Limit: 2 Seconds      Memory Limit: 65536 KB      Special Judge Information ...

随机推荐

  1. Cookie实现留言板

    Cookie实现留言板 直接代码: <!DOCTYPE html> <html> <head> <meta http-equiv="Content- ...

  2. 纯css模仿天猫首页

    <style> *{margin:0;padding:0} li{list-style:none} a{text-decoration:none} #wrapper{font: 12px/ ...

  3. Java 反射、注解

    1. 泛型 基本用法.泛型擦除.泛型类/泛型方法/泛型接口.泛型关键字.反射泛型! a. 概述 泛型是JDK1.5以后才有的, 可以在编译时期进行类型检查,且可以避免频繁类型转化! // 运行时期异常 ...

  4. Linux基础之命令练习Day2-useradd(mod,del),groupadd(mod,del),chmod,chown,

    作业一: 1) 新建用户natasha,uid为1000,gid为555,备注信息为“master” 2) 修改natasha用户的家目录为/Natasha 3) 查看用户信息配置文件的最后一行 4) ...

  5. 基础架构之Redis

    项目开发过程中,有些信息的变动频率是很低但又经常访问到,这些信息我们往往放在缓存中,目前在缓存组件中,Redis绝对值得你列入使用计划.更多详细信息可以参考官网 https://redis.io/.这 ...

  6. TE7下的创建组件AxHost失败

    问题比较诡异.时好时坏的.网上的办法试过了,没用. 最后的解决办法是,把项目属性切换到Any CPU,然后勾选 32位优先,切换到界面设计状态,拖放控件,OK:运行,会出现红色提示:再次切换到项目属性 ...

  7. Python unittest模块心得(一)

    关于unittest模块的一些心得,主要是看官网的例子,加上一点自己的理解,官网地址:https://docs.python.org/3.6/library/unittest.html 基础概念介绍: ...

  8. tempdb过大事故记录-sqlserver

    今天收到预警消息,提示磁盘空间已经满了,感觉很奇怪.刚装的新机器怎么可能会磁盘空间不足.登陆看了看 可以看的到tempdb已经65G的了,而且显示是百分百可用.这个就很奇怪了,为什么会出现这种情况呢. ...

  9. Vim快捷输出查找寄存器的内容(去除\<,\>和\V)

    Vim自带的*搜索会自动在单词两头加上\<和\>,使用第三方的vnoremap *,则是加上前缀\V, 当我们想要输出刚刚搜索的内容时可用<C-r>/,但是很可能会带上多余的符 ...

  10. asp.net c# 断点续传 下载 Accept-Ranges

    转自:http://www.cnblogs.com/90nice/p/3489287.html 1.因为要下载大文件 需要断点续传,使用多线程 分段下载 效率比较高,节省资源. 发点牢骚:下载可以用多 ...