poj3660 ,大致就是, 已有一些奶牛顺序,再去把这个顺序拓展开。
这里的闭包是,根据已有的奶牛顺序,确定出所有可以确定的奶牛顺序。
比如 我们知道 :
1<2
2<3
我们通过闭包运算,经过处理得到三组不等式:
1<2
2<3
1<3
而算法角度,任意两点的大小关系,用floyd再好不过。根据已有的奶牛顺序,确定出所有可以确定的奶牛顺序,最后再判断,是否某个点,总能和其他的所有点都能有大小关系,那么他就是可确定名次的了。
代码如下
package coding;
import java.io.BufferedInputStream;
import java.util.Scanner;
public class poj3660 {
static private final int inf= 0x3f3f3f;
static int [][]map;
static int n,m;
static int floyd() {
//典型floyd , 咱这里求个闭包
for(int i=1;i<=n;i++) {
for(int j= 1;j<=n;j++) {
for(int k=1;k<=n;k++) {
if(map[i][j]==1&& map[k][i]==1) map[k][j]=1;
if(map[i][j]==-1&& map[k][i]==-1) map[k][j]=-1;
}
}
}
int res=0; //判断到现在可以确定名次的有谁
for(int i =1;i<=n;i++) {
int temp=0;
for(int j=1;j<=n;j++) {
if(map[i][j]==1 || map[i][j]== -1 ||map[i][j]==2) temp++;
}
if(temp==n) res++;
}
return res;
}
public static void main(String[] args) {
Scanner sc = new Scanner (new BufferedInputStream(System.in));
n = sc.nextInt();
m = sc.nextInt();
map = new int [n+2][n+2];
for(int i=0;i<=n;i++) map[i][i]=2;
for(int i=0;i<m;i++) {
int a = sc.nextInt();
int b = sc.nextInt();
map[a][b] = 1;
map[b][a] = -1;
}
System.out.println(floyd());
}
}