poj3660

来源:互联网 发布:mac如何设置搜狗输入法 编辑:程序博客网 时间:2024/05/22 12:28

从网上拷贝别人的。这应该算是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 10001int 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]));                          }                        }                           }}


0 0