专栏文章
CF1438C 题解
CF1438C题解参与者 3已保存评论 2
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @mir00o4q
- 此快照首次捕获于
- 2025/12/04 13:31 3 个月前
- 此快照最后确认于
- 2025/12/04 13:31 3 个月前
前言:和机房初二 Master 大神 duel 的时候做到了这题,看到 2-SAT 标签豁然开朗,结果险胜。
注意到这道题每一个格子都有 和 两种状态,可以对应布尔型变量,自然而然就能想到 2-SAT。
我们不妨考虑如何建图。注意到:
-
如果两个格子相邻且相等,两个格子中至少要有一个是 ,至少要有一个是 ,否则依然相等。
-
如果两个格子相邻且差 ,较小的格子为 或者较大的格子为 ,否则这两个格子相等。
于是我们建图跑 Tarjan 就做完了。
CPP#include<bits/stdc++.h>
using namespace std;
int t, n, m, a[105][105];
int dx[] = {0, 1, -1, 0, 0}, dy[] = {0, 0, 0, 1, -1};
int tid(int x, int y){
return (x - 1) * m + y;
}
bool Invalid(int x, int y){
if (x < 1 || y < 1 || x > n || y > m)
return 1;
else
return 0;
}
vector<int> G[2000005], SCC[2000005];
int ig[2000005], dfn[2000005], low[2000005], col[2000005], vl[2000005];
int a1, a2, cnt, ign, ans, ccnt;
bool vis[2000005], vvis[2000005];
stack<int> s;
queue<int> q;
void tarjan(int u){
dfn[u] = low[u] = ++cnt;
s.push(u);
vis[u] = 1;
for (auto &v : G[u]){
if (!dfn[v]){
tarjan(v);
low[u] = min(low[u], low[v]);
}else if (vis[v])
low[u] = min(low[u], dfn[v]);
}
if (dfn[u] == low[u]){
ccnt++;
while (!s.empty()){
int v = s.top();
s.pop();
vis[v] = 0;
col[v] = ccnt;
SCC[u].push_back(v);
if (u == v)
break;
}
}
}
void addedge(int u, int a, int v, int b){
G[u + n * m * a].push_back(v + n * m * (b ^ 1));
G[v + n * m * b].push_back(u + n * m * (a ^ 1));
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin >> t;
while (t--){
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> a[i][j];
for (int i = 1; i <= ccnt; i++)
SCC[i].clear();
for (int i = 1; i <= 2 * n * m; i++){
G[i].clear();
vis[i] = 0;
col[i] = 0;
low[i] = dfn[i] = 0;
}
cnt = ccnt = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++){
for (int k = 1; k <= 4; k++){
int nx = i + dx[k], ny = j + dy[k];
if (Invalid(nx, ny))
continue;
if (a[nx][ny] == a[i][j]){
int u, a, v, b;
u = tid(i, j), v = tid(nx, ny);
a = 1; b = 1;
addedge(u, a, v, b);
a = 0; b = 0;
addedge(u, a, v, b);
}else if (a[nx][ny] == a[i][j] + 1){
int u, a, v, b;
u = tid(i, j), v = tid(nx, ny);
a = 0, b = 1;
addedge(u, a, v, b);
}else if (a[nx][ny] == a[i][j] - 1){
int u, a, v, b;
u = tid(i, j), v = tid(nx, ny);
a = 1, b = 0;
addedge(u, a, v, b);
}
}
}
for (int i = 1; i <= 2 * n * m; i++)
if (!dfn[i])
tarjan(i);
// for (int i = 1; i <= 2 * n * m; i++)
// cout << col[i] << " ";
// cout << "\n";
for (int i = 1; i <= n; i++){
for (int j = 1; j <= m; j++)
cout << a[i][j] + (col[tid(i, j)] < col[tid(i, j) + n * m]) << " ";
cout << "\n";
}
}
return 0;
}
相关推荐
评论
共 2 条评论,欢迎与作者交流。
正在加载评论...