题意:有n头牛,编号为1到n,牛比赛啦,现在给出其中一些牛的pk结果,问哪些牛的排名能够确定。
输入 n m
a b
n头牛,给出m个比赛结果,
a b 表示a打赢了b
一头牛,如果能够确定他的排名,则这头牛的入度和出度之和必定为n-1.
dis[i][j] 为1时表示从i能够到达j,即i的排名在j的前面。为0 时表示i,j不能确定。
a[i] 表示确定了排名在i前面的个数。
b[i] 表示确定了排名在i后面的个数。
首先用floyd扫一遍,确定了哪些点能够到达哪些点,
再扫一遍,求出a,b数组的值,
再扫一遍,找出满足a[i]+b[i]+1==n的点i的个数。
1 #include<cstdio> 2 #include<cstring> 3 const int maxn=110; 4 int dis[maxn][maxn]; 5 int a[maxn]; 6 int b[maxn]; 7 void floyd(int n) 8 { 9 for(int k=1;k<=n;k++) 10 for(int i=1;i<=n;i++) 11 for(int j=1;j<=n;j++) 12 dis[i][j]=dis[i][j]||(dis[i][k]&&dis[k][j]); 13 } 14 int query(int n) 15 { 16 for(int i=1;i<=n;i++) 17 for(int j=1;j<=n;j++) 18 if(i!=j&&dis[i][j]){ 19 a[i]++; 20 b[j]++; 21 } 22 int ans=0; 23 for(int i=1;i<=n;i++) 24 if(a[i]+b[i]+1==n) 25 ans++; 26 return ans; 27 } 28 int main() 29 { 30 int n; 31 while(scanf("%d",&n)!=EOF){ 32 int m,u,v; 33 scanf("%d",&m); 34 memset(dis,0,sizeof(dis)); 35 memset(a,0,sizeof(a)); 36 memset(b,0,sizeof(b)); 37 for(int i=1;i<=m;i++){ 38 scanf("%d%d",&u,&v); 39 dis[u][v]=1; 40 } 41 floyd(n); 42 printf("%d ",query(n)); 43 } 44 return 0; 45 }