[THUSC2017][斯坦纳树+随机化]巧克力

题面

[题目描述]

“人生就像一盒巧克力,你永远不知道吃到的下一块是什么味道。”
明明收到了一大块巧克力,里面有若干小块,排成 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 0ai,j106),这个值越大,表示这一小块巧克力越美味。
正当明明咽了咽口水,准备享用美味时,舟舟神奇地出现了。看到舟舟恳求的目光,明明决定从中选出一些小块与舟舟一同分享。
舟舟希望这些被选出的巧克力是连通的(两块巧克力连通当且仅当他们有公共边),而且这些巧克力要包含至少 k k k ( 1 ≤ k ≤ 5 1 ≤ k ≤ 5 1k5 ) 种。而那些被挤压过的巧克力则是不能被选中的。
明明想满足舟舟的愿望,但他又有点“抠”,想将美味尽可能多地留给自己。所以明明希望选出的巧克力块数能够尽可能地少。如果在选出的块数最少的前提下,美味值的中位数(我们定义 n n n 个数的中位数为第 ⌊ n + 1 2 ⌋ ⌊\frac{n+1}{2}⌋ 2n+1小的数)能够达到最小就更好了。
你能帮帮明明吗?

[输入格式]

从标准输入读入数据。
每个测试点包含多组测试数据。
输入第一行包含一个正整数 T T T ( 1 ≤ T ≤ 5 1 ≤ T ≤ 5 1T5),表示测试数据组数。
对于每组测试数据:
输入第一行包含三个正整数 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,jmid,如果是就赋值为-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 b0,也就是 a n s ≤ ( a n s + M 2 ) M × M ans≤\frac{(ans+\frac{M}{2})}{M}\times M ansM(ans+2M)×M(除法向下取整)。(不用检验 a a a,因为每次我们只改变了第二维 b b b)
这样我们就能够拿到50分的好成绩。

随机化

然而本题的颜色数量实在是太大了,无法状压,这时神仙操作就来了。
我们每次可以将每种颜色随机分配成 1 − k 1-k 1k种不同的颜色,每次随机找最小值,随机到一定次数就可以找到最小值。
为什么这个算法是对的?是因为题目要求至少 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×104了,因此基本上可以认为它是一个正确的算法。
复杂度: 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完全跑满的情况下才会发生的,这是网格图,因此完全可以通过本题。

实现

[对不起,它咕了…]

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值