从网上拷贝别人的。这应该算是Floyd算法的入门题目了吧。网上说这是一道传递闭包问题。用矩阵来存储节点之间的输赢关系。
首先程序中iT[i][i]置1.
当输入A,B时,iT[A][B]置1,算法的关键在于Floyd算法,i与j之间到底可不可以决定谁胜谁负呢?
那要看iT[i][j]或者借助中间节点k使得(iT[i][k]&&iT[k][j)是否为1,这样经过3层循环之后,任意两个节点之间凡是可以
确定输赢关系的都已就绪了。接下来,回到主程序,开始遍历每个节点,如果该节点与其余iNum-1个节点之间的输赢关系
都能确定,则该节点名次可以确定,只要有一个不确定,该节点名次就不确定。这在程序中对应于tmp是否等于iNum.
有一个小地方需要注意,就是在确定tmp时,iT[i][j]或者iT[j][i]为1都要使tmp加1,因为题目只是为了确定i与j的输赢关系,而不是看
i赢的次数。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#define MAXN 101
#define INF 10001
int iNum,iPair;
int iT[MAXN][MAXN];
void transitiveClosure();
int main()
{
int i,j;
int A,B;
int tmp,ans;
scanf("%d%d",&iNum,&iPair);
for(i=1;i<=iNum;i++)
{
for(j=1;j<=iNum;j++)
{
if(i==j)
{
iT[i][j]=1;
continue;
}
iT[i][j]=0;
}
}
for(i=1;i<=iPair;i++)
{
scanf("%d%d",&A,&B);
iT[A][B]=1;
}
transitiveClosure();
ans=0;
for(i=1;i<=iNum;++i)
{
tmp=0;
for(j=1;j<=iNum;++j)
{
if(iT[i][j]||iT[j][i]) ++tmp;
}
if(tmp==iNum) ++ans;
}
printf("%d\n",ans);
return 0;
}
void transitiveClosure()
{
int i,j,k;
for(k=1;k<=iNum;k++)
{
for(i=1;i<=iNum;i++)
{
for(j=1;j<=iNum;j++)
{
iT[i][j]=(iT[i][j]||(iT[i][k]
&&iT[k][j]));
}
}
}
}