P3430 [POI2005]DWU-Double-row
题意:给定长为 $n$ 的序列 $a,b$,你可以选定 $m$ 个位置 $p_i$ 交换 $a_{p_i},b_{p_i}$,使得 $a$ 中不存在相同元素,$b$ 中同理。最小化 $m$。
看到相等,不等,二元运算。好啊,非常显然,建图!问题来了,怎么建图?
什么是点?把同一个位置上的 $a_i,b_i$ 看成一个点。
什么是边?考虑如果两个点的位置有相同元素则建边。怎么区分同位与异位?$0/1$ 边权!
也就是说,如果 $a_u=a_v$ 或 $b_u=b_v$ 则 $u,v$ 建一条边权为 $1$ 的边,否则边权为 $0$。
至此建图完成。
建完图了,现在怎么做?
考虑一次操作,图有什么变化。
对一个位置 $u$ 的 $a_u,b_u$ 交换,那么与其相连的同位变成异位,异位变成同位,也就是与其相邻的所有边边权取反。
既然最终全都不同,那么最终状态就是边权全部为 $0$。
瞎口胡了一下,到这里好像就可以高消做了,然而我不会也不知道对不对。/kk
于是这里有一个套路化的想法就是对于每个点黑白染色,钦定一个连通块上任意一个点为白色($c_i=0$)。
-
若 $u$ 到 $v$ 的边权为 $1$ 则 $c_u\neq c_v$。
-
若 $u$ 到 $v$ 的边权为 $0$ 则 $c_u= c_v$。
这样我们对所有白色结点操作一遍,或者对所有黑色结点操作一遍都可以达到边权全部为 $0$ 的效果。
正确性证明:对于一条边,如果边权为 $1$ 那么其两个端点一定一个为 $0$ 一个为 $1$,这条边会被操作一次变成 $0$。如果边权为 $0$,则会被这条边要么不被操作要么被取反两次,还是 $0$。
所以一个连通块边权为 $0$ 的最小代价为白色结点数量与黑色结点数量的较小者。
跑 dfs 即可。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e5 + 10;
const int maxv = 1e6 + 10;
struct edge { int to, next, w; };
int n, ans;
int a[maxn], b[maxn];
vector<int> p[maxv];
int head[maxn];
edge e[maxn << 2];
int cnt;
void add_edge(int u, int v, int w) {
e[++cnt] = {v, head[u], w};
head[u] = cnt;
}
int vis[maxn], c[2];
void dfs(int u, int f) {
++c[f];
vis[u] = true;
for (int i = head[u]; i; i = e[i].next) {
int v = e[i].to, w = e[i].w;
if (!vis[v]) dfs(v, f ^ w);
}
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) cin >> b[i];
for (int i = 1; i <= n; i++) if (a[i] != b[i]) p[a[i]].push_back(i), p[b[i]].push_back(i);
for (int i = 1; i < maxv; i++) {
if (p[i].size() == 2) {
int u = p[i][0], v = p[i][1], f = (a[u] == a[v] || b[u] == b[v]);
add_edge(u, v, f), add_edge(v, u, f);
}
}
for (int i = 1; i <= n; i++) {
if (!vis[i]) {
c[0] = c[1] = 0;
dfs(i, 0);
ans += min(c[0], c[1]);
}
}
cout << ans << endl;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)