icpc 21沈阳B题 Bitwise Exclusive-OR Sequence
知道两数的异或值,等价于知道两数二进制下的每位是否相等
那么知道了其中一个值,另一个也唯一确定;如果把所有关系建图,那么只要知道某个结点的权值,同一个连通块内的其他点权也唯一确定
进行两次dfs,第一次判断是否合法,第二次按位黑白染色,将较少的颜色所在位赋为1即可
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int head[N], idx;
int vis[N];
int clr[N][31], cnt[3];
struct NODE {
int to, next, w;
} eg[N << 1];
void add(int u, int v, int w) {
eg[idx].to = v;
eg[idx].w = w;
eg[idx].next = head[u];
head[u] = idx++;
}
void dfs_1(int u, int now) {
vis[u] = now; // 当前结点赋值
for (int i = head[u]; ~i; i = eg[i].next) {
int v = eg[i].to;
if (vis[v] == -1) dfs_1(v, now ^ eg[i].w); // 如果没有被访问,就直接进入
else if (vis[v] != (now ^ eg[i].w)) { // 确定了一个值,同一个连通块的所有值都唯一确定,如果有冲突肯定非法
cout << -1 << "\n";
exit(0);
}
}
}
void dfs_2(int u, int now, int p) {
clr[u][p] = now; // 当前结点染色
cnt[now]++;
for (int i = head[u]; ~i; i = eg[i].next) {
int v = eg[i].to;
if (!clr[v][p]) {
if (eg[i].w >> p & 1) dfs_2(v, 3 - now, p); // 如果边权的当前位是1,那么两个结点的当前位不同
else dfs_2(v, now, p); // 反之相等
}
}
}
void work() {
memset(vis, -1, sizeof vis);
memset(head, -1, sizeof head);
int n, m;
cin >> n >> m;
while (m--) {
int u, v, w;
cin >> u >> v >> w;
add(u, v, w), add(v, u, w); // 连双向边,权值为w
}
long long res = 0;
for (int i = 1; i <= n; i++) if (vis[i] == -1) dfs_1(i, 0); // 如果之前没有被访问,就dfs判断是否合法
for (int i = 1; i <= n; i++) { // 第二次dfs统计答案
if (!clr[i][0]) { // 如果没有被染色
for (int j = 0; j <= 30; j++) {
cnt[1] = cnt[2] = 0; // 记录黑白颜色的数量
dfs_2(i, 1, j); // 黑白染色
res += 1ll * min(cnt[1], cnt[2]) * (1 << j); // 取其中较少的
}
}
}
cout << res << "\n";
}
int main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int test = 1;
while (test--) work();
return 0;
}

浙公网安备 33010602011771号