题意
给一个 n n n个 点, m m m 条边的带边权无向图和一个整数 k k k 。请你求出这张图第 k k k 小的生成树的权值和。两棵生成树被认为是不同的当且仅当存在一条边 e e e 使得其在一棵树中,而不在另一棵树中。
子任务1(9pts):满足 1 ≤ n ≤ 10 , 1 ≤ m ≤ 20 , 1 ≤ k ≤ 100 1 \le n \le 10,1 \le m \le 20,1 \le k\le 100 1≤n≤10,1≤m≤20,1≤k≤100。
子任务2(12pts):满足 1 ≤ n ≤ 15 , 1 ≤ m ≤ 150 , 1 ≤ k ≤ 100 1 \le n \le 15,1 \le m \le 150, 1 \le k \le 100 1≤n≤15,1≤m≤150,1≤k≤100
子任务3(19pts):满足 1 ≤ n ≤ 50 , 1 ≤ m ≤ 200 , 1 ≤ k ≤ 100 1 \le n \le 50,1 \le m \le 200,1 \le k \le 100 1≤n≤50,1≤m≤200,1≤k≤100
子任务4(23pts):满足 1 ≤ n ≤ 50 , 1 ≤ m ≤ 1000 , 1 ≤ k ≤ 1000 1 \le n \le 50,1 \le m \le 1000,1 \le k \le 1000 1≤n≤50,1≤m≤1000,1≤k≤1000
子任务5(37pts):满足 1 ≤ n ≤ 50 , 1 ≤ m ≤ 2000 , 1 ≤ k ≤ 10000 1 \le n \le 50,1 \le m \le 2000, 1 \le k \le 10000 1≤n≤50,1≤m≤2000,1≤k≤10000
题解
暴力的想法是先求出最小生成树,用一个堆维护当前最优解,每次把目前最优解(即第 x x x小生成树)的一条边替换成不小于它且替换后仍使图联通的边,并用哈希判重,效率 O ( n m k l o g n ) O(nmklogn) O(nmklogn)。
首先感觉这样哈希判重很不优美,考虑能否使前 k k k小生成树被不重不漏地枚举到,即每种生成树只被一种方式生成。发现把边按照权值标号后,换边时只会把编号小的边换成编号大的边。问题在于以不同顺序换掉两条边会生成相同的树,所以考虑使得每次换掉的边一定是会被换的边中编号最小的,即一条边被换后其前面的边不能被换。
当我们选择换掉一条边时,如果枚举换成哪条边效率太低,有发现对下一个最优解有用的只有换成编号最小的边,而换成其他边的方案也能在之后找到,这样维护最优解的效率就是 O ( n k l o g ) O(nklog) O(nklog)的,查找的效率是 O ( k n m ) O(knm) O(knm)的,但显然跑不满,可以通过。
M
L
E
MLE
MLE警示:
不要试图利用值域为
5
e
7
5e7
5e7用
v
e
c
t
o
r
vector
vector去掉
l
o
g
log
log,这会
M
L
E
MLE
MLE
一些
S
T
L
STL
STL的空间:
v
e
c
t
o
r
vector
vector
24
24
24
s
t
a
c
k
/
q
u
e
u
e
/
d
e
q
u
e
stack/queue/deque
stack/queue/deque 80$
m
a
p
/
s
e
t
map/set
map/set
48
48
48