[最大流建图]最优标号

给定一个无向图 (G=(V,E)) , 每个顶点都有一个标号,它是一个 ([0,2^{31}−1]) 内的整数。

不同的顶点可能会有相同的标号。

对每条边 ((u,v)) ,我们定义其费用 (cost(u,v))(u) 的标号与 (v) 的标号的异或值。

现在我们知道一些顶点的标号。

你需要确定余下顶点的标号使得所有边的费用和尽可能小。

每一个位其实都是独立的,* 表示没有权值,只要有一条路径从 1 0 就至少会产生 1 的贡献

void build(int xx) {
	memset(head, -1, sizeof head);
	tot = 0;

	rep(i, 1, m) {
		addEdge(x[i], y[i], 1);
		addEdge(y[i], x[i], 1);
	}
	rep(i, 1, n) {
		if (A[i] > 0) {
			if ((A[i] >> xx) & 1) addEdge(i, t, inf);
			else addEdge(s, i, inf);
		}
		
	}
}
int main() {
	scanf("%d%d", &n, &m);
	rep(i, 1, m) {
		scanf("%d%d", x + i, y + i);
	}
	scanf("%d", &k);
	memset(A, -1, sizeof A);
	rep(i, 1, k) {
		int a, x; scanf("%d%d", &a, &x);
		A[a] = x;
	}

	long long ans = 0;
	s = 0, t = n + 1;
	rep(i, 0, 30) {
		build(i);
		ans += (1ll*Dinic() << i);
	};
	printf("%lld
", ans);

}
原文地址:https://www.cnblogs.com/sduwh/p/13879296.html