POJ - 3660 Cow Contest (闭包传递)

POJ - 3660 题目链接

闭包传递问题

在这个例子中,很明显,排序后(1,2,(3,4,5),6)我们是不能够确定各个点的位置关系的,3,4,5的关系是无法确定的。
POJ - 3660 Cow Contest (闭包传递)_第1张图片

但是如果我们加上两条边3 -> 4,4 -> 5。
发现我们可以确定3,4,5的关系了,排序变成1,2,3,4,5,6的关系,
POJ - 3660 Cow Contest (闭包传递)_第2张图片

通过这两个例子大家应该都明白了,其实顺序是一个指向的关系,要确定两个点的关系很简单,就只有两种关系a -> b,b -> a。
同样的我们可以类比到n个点上,要确定一个点的关系,我们必须有从这个点出发的指向其他点的边,或者从其他点指向这个点的边

代码

#include
#include
#include
#include
#include
#include
using namespace std;
const int N = 110;
int maze[N][N], n, m;
int floyd() {
	for(int k = 1; k <= n; k++)
		for(int i = 1; i <= n; i++)
			for(int j = 1; j <= n; j++)
				if(maze[i][k] && maze[k][j])
					maze[i][j] = 1;
	int ans = 0;
	for(int i = 1; i <= n; i++) {
		int sum = 0;
		for(int j = 1; j <= n; j++)
			if(maze[i][j] || maze[j][i])
				sum++;
		if(sum == n - 1)	ans++;
	}
	return ans;
}
int main() {
	// freopen("in.txt", "r", stdin);
	int x, y;
	while(scanf("%d %d", &n, &m) != EOF) {
		memset(maze, 0, sizeof maze);
		for(int i = 0; i < m; i++) {
			scanf("%d %d", &x, &y);
			maze[x][y] = 1;
		}
		printf("%d\n", floyd());
	}
	return 0;
}

你可能感兴趣的:(POJ - 3660 Cow Contest (闭包传递))