专栏文章
题解:P14299 [JOI2023 预选赛 R2] 填充 / Painting
P14299题解参与者 3已保存评论 2
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @minh1o65
- 此快照首次捕获于
- 2025/12/02 02:17 3 个月前
- 此快照最后确认于
- 2025/12/02 02:17 3 个月前
这哪是好题了。不是一个很水的搜索吗。
首先我们开一个 的并查集,按顺序给矩阵标号,第 行第 个即为 。
然后把相邻颜色相同的全部合并,统计一下每个联通块的大小和颜色。
然后对每个联通块进行搜索,把相邻的联通块编号塞进一个 set,退出搜索后枚举哪个联通块最大。此时把该联通块的颜色改成这个最大联通块的颜色,所得答案就是这个联通块的最优解。
用一个变量 依次比较记录最大答案即可。
CPP
#include <bits/stdc++.h>
#define int long long
#define lint long long
#define endl '\n'
using namespace std;
const int N = 5e2+5;
const int dx[4] = {1,0,-1,0};
const int dy[4] = {0,1,0,-1};
struct node{
int num;
int col;
}a[N][N];
int n,m,f[N*N];
int sz[N*N],col[N*N];
bitset<1> vis[N][N];
set<int > s;
map<int,int > table;
inline int find(int x){
if(f[x] == x) return x;
return f[x] = find(f[x]);
}
inline void merge(int x,int y){
int fx = find(x);
int fy = find(y);
if(fx != fy) f[fx] = fy;
}
inline void dfs(int x,int y){
vis[x][y].set();
for(int idx = 0; idx < 4; idx++){
int tx = x + dx[idx];
int ty = y + dy[idx];
if(tx < 1 || tx > n || ty < 1 || ty > m) continue;
if(a[tx][ty].col == a[x][y].col && vis[tx][ty] == false) dfs(tx,ty);
else if(a[tx][ty].col != a[x][y].col) s.insert(f[a[tx][ty].num]);
}
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n >> m;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
cin >> a[i][j].col;
a[i][j].num = (i-1) * m + j;
f[a[i][j].num] = a[i][j].num;
if(i > 1 && a[i-1][j].col == a[i][j].col) merge(a[i][j].num,a[i-1][j].num);
if(j > 1 && a[i][j-1].col == a[i][j].col) merge(a[i][j].num,a[i][j-1].num);
}
}
int ans = 0;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
sz[find(a[i][j].num)]++;
col[f[a[i][j].num]] = a[i][j].col;
ans = max(ans,sz[f[a[i][j].num]]);
}
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
if(vis[i][j] == true)
continue;
dfs(i,j);
for(int val : s){
if(table.find(col[val]) == table.end())
table[col[val]] = sz[val];
else table[col[val]] += sz[val];
}
int maxCol = 0;
for(auto val : table)
if(!maxCol || table[maxCol] < val.second)
maxCol = val.first;
ans = max(ans,sz[f[a[i][j].num]]+table[maxCol]);
s.clear(),table.clear();
}
}
cout << ans << endl;
return 0;
}
相关推荐
评论
共 2 条评论,欢迎与作者交流。
正在加载评论...