1. 程式人生 > 實用技巧 >[最大流建圖]最優標號

[最大流建圖]最優標號

給定一個無向圖 \(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\n", ans);

}