洛谷题面传送门

9.13 补之前 8.23 做的题,不愧是鸽子 tzc(

首先我们先来探讨一下如果 \(c_{i,j}\le k\) 怎么做,先考虑第一问。显然一个连通块符合条件当且仅当它能够包含所有颜色。我们注意到这里的 \(k\) 数据范围很小,因此考虑状压 \(dp\)。\(dp_{x,y,S}\) 表示包含 \((x,y)\) 且囊括了 \(S\) 中所有颜色的最小连通块的大小。那么有转移 \(dp_{x,y,S}+1\to dp_{x+1,y,S\cup\{c_{x+1,y}\}}\),其余三个方向上的转移也同理。注意这样直接转移有后效性,不过注意到这种后效性只可能发生在 \(c_{x+1,y}\in S\) 的情况,因此我们考虑这样转移:从小到大枚举 \(S\),然后对于每个 \(dp_{x,y,S}\) 更新 \(dp_{x,y,S}=\min\limits_{S_1\cup S_2=S}\{dp_{x,y,S_1}+dp_{x,y,S_2}-1\}\),之后再用 \(dp_{x,y,S}\) 去更新周围的点,即 \(dp_{x,y+1,S}\leftarrow dp_{x,y,S}+1\),类似于一个最短路的过程。不难发现上述过程中使用了取 \(\min/\max\) 的 DP 的一个思想:我的 DP 转移贡献不一定合法,但我不合法的情况肯定没有合法的情况来得更优。在上面的 DP 转移中有可能出现转移到的 \(S\) 等于我们转移所产生贡献的连通块真正包含的颜色集合,但这个包含关系是必然成立的,因此最优解肯定会被我囊括在内。据说这就是斯坦纳树的基本思想?反正也算一个非常 trivial 的知识点吧(

接下来考虑第二问。其实也非常套路吧……考虑二分中位数 \(mid\),然后把 \(\le mid\) 都设为 \(-1\),\(>mid\) 都设为 \(1\),这样可以仿照之前的解法求出在满足连通块大小最小的情况,最小的权值和,如果最小权值和 \(\le 0\) 则说明这个中位数符合条件,应向左二分,否则应向右二分。正确性显然,总复杂度大概是 \(2^k·\log^2(nm)·nm\)​。

接下来考虑原问题。显然对于原题的数据范围而言,直接上个状压 dp 就不可取了。不过这个思想还是很有启发意义的。考虑最优解连通块中的颜色种类 \(S\),我们希望能够重新分组使得颜色个数 \(\le k\),并且恰好满足 \(S\) 中的颜色被分在了至少 \(k\) 组中,有什么好方法呢?随机化,考虑随机将 \(nm\) 种颜色分组,那么最优解刚好被分在 \(k\) 个不同的组中的概率大概是 \(\dfrac{k!}{k^k}\),当 \(k=5\) 时这个概率大概在百分之几,随机个 \(150\) 次出错的概率就很低了。

时间复杂度 \(T·150·2^k·\log^2(nm)·nm\)​,非常卡常。然后我反向套路一波,把 dij 换成 SPFA(真·网格图 SPFA)就过了(?)

const int MAXN=233;
const int MAXP=32;
const int INF=1061109567;
const int dx[]={1,0,-1,0};
const int dy[]={0,1,0,-1};
int n,m,k,a[MAXN+5][MAXN+5],c[MAXN+5][MAXN+5];
int va[MAXN+5],col[MAXN+5],id[MAXN+5][MAXN+5],cc[MAXN+5],cnt=0;
int hd[MAXN+5],to[MAXN*4+5],nxt[MAXN*4+5],ec=0;
void adde(int u,int v){to[++ec]=v;nxt[ec]=hd[u];hd[u]=ec;}
bool vis[MAXN+5];
pii dp[MAXN+5][MAXP+5],b[MAXN+5];
pii operator +(pii x,pii y){return mp(x.fi+y.fi,x.se+y.se);}
pii operator -(pii x,pii y){return mp(x.fi-y.fi,x.se-y.se);}
void dijkstra(int s){
queue<int> q;
for(int i=1;i<=cnt;i++) q.push(i),vis[i]=1;
while(!q.empty()){
int x=q.front();q.pop();vis[x]=0;
for(int e=hd[x];e;e=nxt[e]){
int y=to[e];
if(dp[y][s]>dp[x][s]+b[y]){
dp[y][s]=dp[x][s]+b[y];
if(!vis[y]) vis[y]=1,q.push(y);
}
}
}
}
pii check(int mid){
for(int i=1;i<=cnt;i++) for(int s=0;s<(1<<k);s++) dp[i][s]=mp(INF,INF);
for(int i=1;i<=cnt;i++){
if(va[i]<=mid) dp[i][1<<(col[i]-1)]=dp[i][0]=b[i]=mp(1,-1);
else dp[i][1<<(col[i]-1)]=dp[i][0]=b[i]=mp(1,1);
}
for(int s=0;s<(1<<k);s++){
for(int i=1;i<=cnt;i++){
for(int t=(s-1)&s;t;t=(t-1)&s) chkmin(dp[i][s],dp[i][t]+dp[i][s^t]-b[i]);
} dijkstra(s);
} pii res=mp(INF,INF);
for(int i=1;i<=cnt;i++) chkmin(res,dp[i][(1<<k)-1]);
return res;
}
pii work(){
int l=0,r=1e6,res=check(0).fi,p=INF;
if(res==INF) return mp(INF,INF);
while(l<=r){
int mid=l+r>>1;
if(check(mid).se<=0) p=mid,r=mid-1;
else l=mid+1;
}
return mp(res,p);
}
void clear(){
memset(hd,0,sizeof(hd));ec=0;
memset(id,0,sizeof(id));cnt=0;
}
void solve(){
scanf("%d%d%d",&n,&m,&k);pii res=mp(INF,INF);clear();
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&c[i][j]);
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&a[i][j]);
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(~c[i][j]) id[i][j]=++cnt,va[cnt]=a[i][j];
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) for(int d=0;d<4;d++){
int x=i+dx[d],y=j+dy[d];
if(x<1||x>n||y<1||y>m||!id[x][y]) continue;
adde(id[i][j],id[x][y]);
}
int ______=150;
while(______--){
for(int i=1;i<=n*m;i++) cc[i]=rand()%k+1;
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)
if(id[i][j]) col[id[i][j]]=cc[c[i][j]];
chkmin(res,work());
} if(res.fi==INF) printf("-1 -1\n");
else printf("%d %d\n",res.fi,res.se);
}
int main(){
srand(20210823183524ll&4294967295);
int qu;scanf("%d",&qu);while(qu--) solve();
return 0;
}

洛谷 P7450 - [THUSCH2017] 巧克力(斯坦纳树+随机化)的更多相关文章

  1. loj2977 巧克力 (斯坦纳树+随机化)

    考虑颜色比较少的时候,第一问可以直接斯坦纳树 第二问考虑二分,每次把每格的权值给成1000+[a[i]>m],就是在个数最少的基础上尽量选小于等于m的 然而颜色太多不能直接做,但可以把每种颜色映 ...

  2. LOJ#2977. 「THUSCH 2017」巧克力(斯坦纳树+随机化)

    题目 题目 做法 考虑部分数据(颜色较少)的: 二分中位数\(mid\),将\(v[i]=1000+(v[i]>mid)\) 具体二分操作:然后求出包含\(K\)种颜色的联通快最小的权值和,判断 ...

  3. 【THUSC2017】【LOJ2977】巧克力 斯坦纳树

    题目大意 有一个网格(或者你可以认为这是一个图),每个点都有颜色 \(c_i\) 和点权 \(a_i\). 求最小的连通块,满足这个连通块内点的颜色数量 \(\geq k\).在满足点数最少的前提下, ...

  4. [THUSC2017]巧克力[斯坦纳树、随机化]

    题意 题目链接 分析 对于第一问,如果颜色数量比较少的话可以 \(\binom{cnt}{k}\) 枚举最终连通块中的 \(k\) 种颜色,然后利用斯坦纳树求解. 如果颜色比较多,考虑将所有的颜色重新 ...

  5. 【BZOJ2595_洛谷4294】[WC2008]游览计划(斯坦纳树_状压DP)

    上个月写的题qwq--突然想写篇博客 题目: 洛谷4294 分析: 斯坦纳树模板题. 简单来说,斯坦纳树问题就是给定一张有边权(或点权)的无向图,要求选若干条边使图中一些选定的点连通(可以经过其他点) ...

  6. 洛谷P3264 [JLOI2015]管道连接(斯坦纳树)

    传送门 感觉对斯坦纳树还是有很多疑惑啊…… 等到时候noip没有爆零的话再回来填坑好了 //minamoto #include<iostream> #include<cstdio&g ...

  7. 洛谷P3264 [JLOI2015]管道连接 (斯坦纳树)

    题目链接 题目大意:有一张无向图,每条边有一定的花费,给出一些点集,让你从中选出一些边,用最小的花费将每个点集内的点相互连通,可以使用点集之外的点(如果需要的话). 算是斯坦纳树的入门题吧. 什么是斯 ...

  8. LOJ 2997 「THUSCH 2017」巧克力——思路+随机化+斯坦纳树

    题目:https://loj.ac/problem/2977 想到斯坦纳树.但以为只能做 “包含一些点” 而不是 “包含一些颜色” .而且不太会处理中位数. 其实 “包含一些颜色” 用斯坦纳树做也和普 ...

  9. [APIO2013]机器人(斯坦纳树)

    题目描述 VRI(Voltron 机器人学会)的工程师建造了 n 个机器人.任意两个兼容的机 器人站在同一个格子时可以合并为一个复合机器人. 我们把机器人用 1 至 n 编号(n ≤ 9).如果两个机 ...

随机推荐

  1. 免费 CDN 玩法 —— 文件一键上传到 NPM

    前言 unpkg.jsdelivr 等站点可加速 NPM 包文件,适合作为个人网站或演示案例的免费 CDN. 虽然上传文件到 NPM 很简单,创建 package.json 然后 npm publis ...

  2. scala基础篇 使用getter和setter方法而不使用public的情形

    主要是基于2种情形 1) 提供读只取/只写入方法,不能随意读写 2)做赋值时变量控制,比如设定值的区间范围等 例子: object test{ def main(args: Array[String] ...

  3. Promise.resolve(x)中x有几种情况

    ps:下面参数说的是Promise.resolve(x)中的x 一共四种情况: 1.如果参数是Promise实例本身,则抛出错误 2.如果参数是一个promise对象,则then函数的执行取决于这个参 ...

  4. javascript-vue介绍

    vue.js是一个用于创建web交互页面的库 从技术角度讲,vue专注于MVVM模型的viewModel层,它通过双向数据绑定把view层和model层连接起来,实际DOM封装和输出格式都被抽象为Di ...

  5. 为什么阿里巴巴开发手册中强制要求 POJO 类使用包装类型?NPE问题防范

    封面:学校内的秋天 背景:写这个的原因,也是我这两天凑巧看到的,虽然我一直有 alibaba Java 开发手册,也看过不少次,但是一直没有注意过这个问题 属于那种看过,但又没完全看过 一起来看看吧冲 ...

  6. Java:内部类小记

    Java:内部类小记 对 Java 中的 内部类,做一个微不足道的小小小小记 首先:内部类是指在一个外部类的内部再定义一个类.内部类作为外部类的一个成员,并且依附于外部类而存在的. 成员内部类 成员内 ...

  7. springboot读取配置文件中的信息

    在一个项目中,我们有时候会把一些配置信息写入到一个配置文件中,在java代码中读取配置文件的信息.在此记录下读取属性文件中的内容. 在springboot项目中,springboot的配置文件可以使用 ...

  8. Exynos4412 中断处理流程详解

    Linux 中,当外设触发中断后,大体处理流程如下: a -- 具体CPU architecture相关的模块会进行现场保护,然后调用machine driver对应的中断处理handler; b - ...

  9. (转载)linux chmod命令用法

    chmod----改变一个或多个文件的存取模式(mode) chmod [options] mode files   只能文件属主或特权用户才能使用该功能来改变文件存取模式.mode可以是数字形式(八 ...

  10. 数组中出现次数超过一半的数字 牛客网 剑指Offer

    数组中出现次数超过一半的数字 牛客网 剑指Offer 题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字 ...