洛谷题面传送门

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. UltraSoft - Beta - 设计与计划

    在DDL Killer的Alpha发布版本一周后,我们积累了一定的用户数量和用户反馈,同时也着手准备Beta阶段的继续开发,在正式开始迭代前,先对我们的Beta阶段的需求做一个统计和预估,一是保证工作 ...

  2. 【二食堂】Beta - 设计和计划

    Beta设计和计划 需求再分析 根据助教.老师.用户以及各个团队PM的反馈意见,我们的项目目前有以下问题: 功能不完整 实用价值不高 两方面的缺陷,所以在Beta阶段,我们工作的中心还是完成项目规划中 ...

  3. UltraSoft - Beta - Scrum Meeting 2

    Date: May 18th, 2020. Scrum 情况汇报 进度情况 组员 负责 今日进度 q2l PM.后端 建立Beta仓库管理增加服务器部署和Git协作文档 Liuzh 前端 查阅响应式布 ...

  4. 聊聊 Kubernetes Pod or Namespace 卡在 Terminating 状态的场景

    这个话题,想必玩过kubernetes的同学当不陌生,我会分Pod和Namespace分别来谈. 开门见山,为什么Pod会卡在Terminationg状态? 一句话,本质是API Server虽然标记 ...

  5. NavigationView使用简介

    Android支持直接创建带有NavigationView的Activity,这里主要介绍NavigationView的逻辑. NavigationView通常是跟DrawerLayout一起使用.D ...

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

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

  7. hdu 3047 Zjnu Stadium(并查集)

    题意: 300个座位构成一个圈. 有N个人要入座. 共有M个说明 :A B X ,代表B坐在A顺时针方向第X个座位上.如果这个说明和之前的起冲突,则它是无效的. 问总共有多少个无效的. 思路: 并查集 ...

  8. Linux 兴趣小组2016免试题 第四关揭秘

    Linux 兴趣小组2016免试题 点这里 首先贴出第四关链接Linux 兴趣小组2016免试题 第四关 第四关: 进入网址我们看到的是4张扑克牌K,这是什么意思? 要我斗地主?好了,还是乖乖的先查看 ...

  9. 虚拟化与kvm

    cpu指令级别 传统中操作系统运行于R0中称之为特权级别,直接与硬件进行交互. 应用程序运行于r3级别称之为低权限,无法与硬件直接进行交互.也就是说程序是运行于用户态,系统运行于内核态中. 虚拟化要解 ...

  10. Loadrunner12的下载和安装

    工作需要,学起来 第一部分:安装 一.在惠普官网下载Loadrunner12安装包.下载下来将会有四个安装包. HP_LoadRunner_12.02_Community_Edition_Additi ...