洛谷题面传送门

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. python 类中的公有属性 私有属性 实例属性

    class parent(): i=1 __j=2 class child(parent): m=3 __n=4 def __init__(self,age,name): self.age=age s ...

  2. Hadoop MapReduce 保姆级吐血宝典,学习与面试必读此文!

    Hadoop 涉及的知识点如下图所示,本文将逐一讲解: 本文档参考了关于 Hadoop 的官网及其他众多资料整理而成,为了整洁的排版及舒适的阅读,对于模糊不清晰的图片及黑白图片进行重新绘制成了高清彩图 ...

  3. Matlab/Modelsim图像联合仿真平台

    FPGA图像仿真平台 1 引言 在使用modelsim进行图像算法的功能仿真时,无法得到图像的实时预览,因此直观性有所欠缺.因此可配合matlab使用,通过modelsim读出txt格式的图像,利用m ...

  4. Noip模拟43 2021.8.18

    T1 地一体 可以树形$dp$,但考场没写出来,只打了没正确性的贪心水了$30$ 然后讲题的时候B哥讲了如何正确的贪心,喜出望外的学习了一下 不难发现 每次士兵都会直接冲到叶子节点 从深的点再返回到另 ...

  5. 2021.8.18 NKOJ周赛总结

    两个字总结:安详 T1: NKOJ-6179 NP问题 问题描述: p6pou在平面上画了n个点,并提出了一个问题,称为N-Points问题,简称NP问题. p6pou首先在建立的平面直角坐标系,并标 ...

  6. Spring Security:Authentication 认证(一)

    1. Spring Security 简介 在 Spring 生态系统中,为他的项目增加安全性,你可以借助 Spring Security 库来做到这一点. 那什么是 Spring Security? ...

  7. Spring---IoC(控制反转)原理学习笔记【全】

    1.IoC创建对象的方式 使用无参构造创建对象 假如要使用有参构造创建: 下标赋值constructor-arg <!--有参--> <bean id="User" ...

  8. Matlab+Qt开发笔记(一):matlab搭建Qt开发matlib环境以及Demo测试

    前言   做一些数据处理软件,使用matlab文件,.mat文件.   准备条件   安装matlab2016,发现是vs 12(是vs2011版本),Qt5.9.3是支持vs 14(是vs2015版 ...

  9. 数字设计中的时钟与约束(gate)

    转载:https://www.cnblogs.com/IClearner/p/6440488.html 最近做完了synopsys的DC workshop,涉及到时钟的建模/约束,这里就来聊聊数字中的 ...

  10. ffmpeg第7篇:数据流选择神器-map指令

    自动选择规则 ffmpeg在处理视频时,如果只提供了输入和输出参数,ffmpeg会自动地去选择相应的视频流和音频流来合成文件 自动选择的方式根据如下规则: 视频流:选分辨率最高的,比如有两个视频,一个 ...