POJ - 3660 题目链接
闭包传递问题
在这个例子中,很明显,排序后(1,2,(3,4,5),6)我们是不能够确定各个点的位置关系的,3,4,5的关系是无法确定的。
但是如果我们加上两条边3 -> 4,4 -> 5。
发现我们可以确定3,4,5的关系了,排序变成1,2,3,4,5,6的关系,
通过这两个例子大家应该都明白了,其实顺序是一个指向的关系,要确定两个点的关系很简单,就只有两种关系a -> b,b -> a。
同样的我们可以类比到n个点上,要确定一个点的关系,我们必须有从这个点出发的指向其他点的边,或者从其他点指向这个点的边
代码
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
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
", floyd());
}
return 0;
}