BZOJ 1143: [CTSC2008]祭祀river 最大独立集

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 1143: [CTSC2008]祭祀river 最大独立集相关的知识,希望对你有一定的参考价值。

题目链接:

http://www.lydsy.com/JudgeOnline/problem.php?id=1143

题解:

给你一个DAG,求最大的顶点集,使得任意两个顶点之间不可达。

把每个顶点v拆成v和v‘,对于边u,v,建成(u,v‘),得到一个二分图。

先对二分图floyd求闭包,然后求二分图的最大独立集就可以了。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

const int maxn = 111;

int mat[maxn][maxn];
int vis[maxn], lef[maxn];
int n, m;

void init() {
	memset(mat, 0, sizeof(mat));
	memset(lef, 0, sizeof(lef));
}

bool match(int u) {
	for (int i = 1; i <= n; i++) {
		if (mat[u][i]&&!vis[i]) {
			vis[i] = 1;
			if (!lef[i] || match(lef[i])) {
				lef[i] = u;
				return true;
			}
		}
	}
	return false;
}

int main() {
	while (scanf("%d%d", &n, &m) == 2 && n) {
		init();
		for (int i = 0; i < m; i++) {
			int u, v;
			scanf("%d%d", &u, &v);
			mat[u][v] = 1;
		}
		for (int k = 1; k <= n; k++) {
			for (int i = 1; i <= n; i++) {
				for (int j = 1; j <= n; j++) {
					if (mat[i][k] && mat[k][j]) {
						mat[i][j] = 1;
					}
				}
			}
		}
		for (int i = 1; i <= n; i++) {
			memset(vis, 0, sizeof(vis));
			match(i);
		}
		int cnt = 0;
		for (int i = 1; i <= n; i++) {
			if (lef[i] != 0) cnt++;
		}
		printf("%d\n", n - cnt);
	}
	return 0;
}

 

以上是关于BZOJ 1143: [CTSC2008]祭祀river 最大独立集的主要内容,如果未能解决你的问题,请参考以下文章

bzoj1143[CTSC2008]祭祀river

bzoj 1143: [CTSC2008]祭祀river

bzoj1143: [CTSC2008]祭祀river

bzoj1143: [CTSC2008]祭祀river 最长反链

BZOJ 1143: [CTSC2008]祭祀river 最大独立集

BZOJ1143: [CTSC2008]祭祀river