I Curse Myself
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 475 Accepted Submission(s): 76
Problem Description
There is a connected undirected graph with weights on its edges. It is guaranteed that each edge appears in at most one simple cycle.
Assuming that the weight of a weighted spanning tree is the sum of weights on its edges, define
V(k) as the weight of the
k-th smallest weighted spanning tree of this graph, however,
V(k) would be defined as zero if there did not exist
k different weighted spanning trees.
Please calculate
(∑k=1Kk⋅V(k))mod232.
Input
The input contains multiple test cases.
For each test case, the first line contains two positive integers
n,m
(2≤n≤1000,n−1≤m≤2n−3), the number of nodes and the number of edges of this graph.
Each of the next
m lines contains three positive integers
x,y,z
(1≤x,y≤n,1≤z≤106), meaning an edge weighted
z between node
x and node
y. There does not exist multi-edge or self-loop in this graph.
The last line contains a positive integer
K
(1≤K≤105).
Output
For each test case, output "
Case #x: y" in one line (without quotes), where
x indicates the case number starting from
1 and
y denotes the answer of corresponding case.
Sample Input
4 3 1 2 1 1 3 2 1 4 3 1 3 3 1 2 1 2 3 2 3 1 3 4 6 7 1 2 4 1 3 2 3 5 7 1 5 3 2 4 1 2 6 2 6 4 5 7
Sample Output
Case #1: 6 Case #2: 26 Case #3: 493
Source
2017 Multi-University Training Contest - Team 1
Recommend
liuyiding
题目大意:
给你一棵无向带边权的仙人掌(节点数<=1e3),求前k(1<=k<=1e5)小生成树的权值之和。
解题思路:
由于这个图是仙人掌,那么它的生成树就一定是每个环去掉一条边所构成的,我们可以通过存边的tarjan算法找到仙人掌上的所有环,题目要求k小生成树,我们只要找到去掉的边的k大的组合即可。
那么就可把问题简化为:有一些集合,在每个集合中选一个数,求前k大的组合。
官方题解说这就是一个经典问题了。。。可能是我比较菜吧,通过这道题,我才知道这个问题怎么解决。。。。
对于这些集合两两合并(为了方便一个叫A一个叫B),在合并的过程中,先用A中最大值和B中全部元素相加,放到堆中。每次从堆中拿出元素时,用构成这个元素的A中下一个更小的值(如果存在)与之前的B中元素结合放到堆中,直到堆空或得到k个元素。
这样写的复杂度我不是很会推导,引用官方题解:
AC代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include