题解:CF37E Trial for Chief
题目分析
题意
给一张全白的图,每次可以将一个四联通块染黑或染白,求转化到目标最少染色次数。
分析
考虑倒着想,由目标染回原图。
易得倒着染回去和正着染的最少染色次数相同。
所以我们考虑从最后的图入手。
考虑从某一个点
尝试进行建图。
在同样的颜色间转移的代价是
如果颜色不同,就需要至少进行一次染色,所以代价是
建图跑最短路即可。
每次跑完后用距离最大的黑点更新答案。(因为原图是白色,所以只统计黑点)
并且默认一开始需染一次色,所以
发现边权只有
可以考虑使用 0-1 BFS 求最短路。(其实用 0-1BFS 求的话可以不用建图)
时间复杂度
Code
#include<bits/stdc++.h> using namespace std; #define maxn 52 string tmp; int mp[maxn][maxn]; #define pos(i, j) (m*((i)-1)+j) #define chk(i, j) ((i)&&(j)&&(i<=n)&&(j<=m)) vector<pair<int, int> > e[maxn*maxn]; deque<int> dq; int dis[maxn*maxn]; int bfs(int x, int n, int m) { memset(dis, 0x3f, sizeof dis); dis[x]=1; dq.emplace_back(x); while(!dq.empty()) { auto u=dq.front(); dq.pop_front(); for(auto [v, w]:e[u]) if(dis[v]>dis[u]+w) { dis[v]=dis[u]+w; if(w) dq.emplace_back(v); else dq.emplace_front(v); } } int ans=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(mp[i][j]) ans=max(ans, dis[pos(i, j)]); return ans; } int main() { int n, m; cin>>n>>m; for(int i=1;i<=n;i++) { cin>>tmp; for(int j=1;j<=m;j++) mp[i][j]=(tmp[j-1]=='B'); } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if(chk(i-1, j)) e[pos(i, j)].emplace_back(pos(i-1, j), mp[i][j]!=mp[i-1][j]); if(chk(i+1, j)) e[pos(i, j)].emplace_back(pos(i+1, j), mp[i][j]!=mp[i+1][j]); if(chk(i, j-1)) e[pos(i, j)].emplace_back(pos(i, j-1), mp[i][j]!=mp[i][j-1]); if(chk(i, j+1)) e[pos(i, j)].emplace_back(pos(i, j+1), mp[i][j]!=mp[i][j+1]); } int ans=numeric_limits<int>::max(); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) ans=min(ans, bfs(pos(i, j), n, m)); cout<<ans; }
本文作者:Jimmy-LEEE
本文链接:https://www.cnblogs.com/redacted-area/p/18379531
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步