题面
[题目描述]
“人生就像一盒巧克力,你永远不知道吃到的下一块是什么味道。”
明明收到了一大块巧克力,里面有若干小块,排成
n
n
n行
m
m
m列。每一小块都有自己特别的图案
c
i
,
j
c_{i,j}
ci,j,它们有的是海星,有的是贝壳,有的是海螺… 其中还有一些因为挤压,已经分辨不出是什么图案了。明明给每一小块巧克力标上了一个美味值
a
i
,
j
a_{i, j}
ai,j(
0
≤
a
i
,
j
≤
1
0
6
0 ≤ a_{i, j} ≤ 10^6
0≤ai,j≤106),这个值越大,表示这一小块巧克力越美味。
正当明明咽了咽口水,准备享用美味时,舟舟神奇地出现了。看到舟舟恳求的目光,明明决定从中选出一些小块与舟舟一同分享。
舟舟希望这些被选出的巧克力是连通的(两块巧克力连通当且仅当他们有公共边),而且这些巧克力要包含至少
k
k
k (
1
≤
k
≤
5
1 ≤ k ≤ 5
1≤k≤5 ) 种。而那些被挤压过的巧克力则是不能被选中的。
明明想满足舟舟的愿望,但他又有点“抠”,想将美味尽可能多地留给自己。所以明明希望选出的巧克力块数能够尽可能地少。如果在选出的块数最少的前提下,美味值的中位数(我们定义
n
n
n 个数的中位数为第
⌊
n
+
1
2
⌋
⌊\frac{n+1}{2}⌋
⌊2n+1⌋小的数)能够达到最小就更好了。
你能帮帮明明吗?
[输入格式]
从标准输入读入数据。
每个测试点包含多组测试数据。
输入第一行包含一个正整数
T
T
T (
1
≤
T
≤
5
1 ≤ T ≤ 5
1≤T≤5),表示测试数据组数。
对于每组测试数据:
输入第一行包含三个正整数
n
n
n,
m
m
m 和
k
k
k;
接下来
n
n
n 行,每行
m
m
m 个整数,表示每小块的图案
c
i
,
j
c_{i, j}
ci,j。若
c
i
,
j
=
1
c_{i, j}=1
ci,j=1 表示这一小块受到过挤压,不能被选中;
接下来
n
n
n 行,每行
m
m
m 个整数,表示每个小块的美味值
a
i
,
j
a_{i, j}
ai,j。
[输出格式]
输出到标准输出。
输出共包括
T
T
T 行,每行包含两个整数,用空格隔开,即最少的块数和最小的美味值中位数。
若对于某组测试数据,不存在任意一种合法的选取方案,请在对应行输出两个-1
。
[样例1输入]
1
5 4 5
3 4 3 4
5 5 -1 5
-1 4 5 5
5 5 4 2
1 -1 2 4
1 3 1 1
3 2 3 3
4 4 4 5
8 9 9 5
7 2 6 3
[样例1输出]
9 5
[数据范围与提示]
[暂无]
题解
斯坦纳树
是不是跟宝藏
(或者[WC2008]游览计划
)这道题很像?
那么我们也考虑使用斯坦纳树来解决这道题,虽然最后几组数据点颜色数量很多,但我们可以先考虑如何解决规模小的数据。
首先我们要找到最小块数,同宝藏
这道题目一样,我们可以定义
d
i
s
[
x
]
[
y
]
[
S
]
dis[x][y][S]
dis[x][y][S]表示当前在
(
x
,
y
)
(x,y)
(x,y)位置,现在收集到的颜色集合为
S
S
S,同样有两种转移,一种是枚举子集转移,一种是SPFA松弛转移,每个点的代价为1,这样,结合(很难打的)暴力分,我们就可以拿到41分的好成绩。
然后我们考虑如何找到中位数,最常见的套路就是二分中位数,找是否存在一个最小的块使得有
n
2
\frac{n}{2}
2n(向下取整)个数小于
m
i
d
mid
mid,那么设
b
i
,
j
b_{i,j}
bi,j为当前点
(
i
,
j
)
(i,j)
(i,j)是否满足
a
i
,
j
≤
m
i
d
a_{i,j}≤mid
ai,j≤mid,如果是就赋值为-1
否则为1
(注意一定是小于等于,也不能将
a
i
,
j
=
m
i
d
a_{i,j}=mid
ai,j=mid够赋值为0
,当块数为偶数,前面一半都为
m
i
d
mid
mid时,后面的做法是错误的)。
那么我们就相当于维护了两个关键字,每次计算
d
i
s
dis
dis是先比较走过的块数的和(设为
a
a
a),如果相同就比较走过的
b
i
,
j
b_{i,j}
bi,j的和(设为
b
b
b)。然而还有更为简便的做法,就是我们找一个足够大的数
M
M
M,将它压为一个数
a
×
M
+
b
a\times M+b
a×M+b,这样也能够达到同样的效果。这里的
M
M
M我们可以取
1
0
5
10^5
105。
每次检验我们要满足
b
≤
0
b≤0
b≤0,也就是
a
n
s
≤
(
a
n
s
+
M
2
)
M
×
M
ans≤\frac{(ans+\frac{M}{2})}{M}\times M
ans≤M(ans+2M)×M(除法向下取整)。(不用检验
a
a
a,因为每次我们只改变了第二维
b
b
b)
这样我们就能够拿到50分的好成绩。
随机化
然而本题的颜色数量实在是太大了,无法状压,这时神仙操作就来了。
我们每次可以将每种颜色随机分配成
1
−
k
1-k
1−k种不同的颜色,每次随机找最小值,随机到一定次数就可以找到最小值。
为什么这个算法是对的?是因为题目要求至少
k
k
k种颜色,我们将几种颜色看成一种,只会更劣,不会更优。
注意到当我们将答案的
k
k
k种颜色分配成不同的颜色时就是最小值,那么我们每次就有
k
!
k
k
\frac{k!}{k^k}
kkk!的概率可以找到答案,
k
=
5
k=5
k=5时单次概率为
0.0384
0.0384
0.0384,大概重复
t
=
200
t=200
t=200次,失败的概率就只有
3.97
×
1
0
−
4
3.97\times 10^{-4}
3.97×10−4了,因此基本上可以认为它是一个正确的算法。
复杂度:
O
(
T
×
t
×
(
n
m
3
k
+
(
n
m
)
2
2
k
)
)
O(T\times t \times(nm3^k+(nm)^2 2^k))
O(T×t×(nm3k+(nm)22k))
然而这只是SPFA完全跑满的情况下才会发生的,这是网格图,因此完全可以通过本题。
实现
[对不起,它咕了…]