HUD 1285 确定比赛名次

该题是一道拓扑排序,拓扑排序就是每次寻找入度为0的节点,如果没有入度为0的节点但节点并没有完全找出,则该排名失败了;

由于没有图,不好解释,建议你去看一下数据结构,我这里实现的是链表的方法:

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

typedef  struct AOE

{

     int  n;

     struct AOE *next;

}AOE;

struct T

{

    int  n,flag;

    AOE  *next;

}VEX[524];  

void    build(  int   x,   int  y)   //建立表

{

     AOE  *p;

     if(VEX[x].next==NULL)

     {

               VEX[x].next=  ( AOE  *) malloc(  sizeof  (  AOE));

               VEX[x].next->next =  NULL;

               VEX[x].next ->n=y;

               VEX[y].n++;

               return ;

     }  

     p=VEX[x].next;

     while(p->next)

     p  = p->next;

     p->next=  ( AOE  *  ) malloc(  sizeof  (  AOE));

     p->next->next =  NULL;

       p->next->n=y;

       VEX[y].n++;

     

}

void   rank(int   n)

{

      int   i  =1,sum=1;

      while(i<=n)

      {

             if(VEX[ i ].n==0&&!VEX[i].flag)  //寻找入度为0的节点

             {

                        AOE  *p,*q;

                        VEX[i].flag=1;

                        p=VEX[i].next;

                        while(p)

                        {

                               q=p;

                               VEX[p->n].n--;

                               p=p->next;

                               free(q);

                        }

                 printf(sum==n?"%d\n":"%d ",i);

                 sum++;

                 i=0;    //会到节点0重新开始遍历,这个地方可以优化,可以用栈

             }

             i++;

      }

}

int main( )

{

    int  n,m,x,y;

    while (  scanf("%d%d" ,  &n,&m)!=EOF)

    {

            for(int  i=0;i<=n;i++)

            {

                 VEX[i].flag=0;

                 VEX[i].n=0;

                 VEX[i].next=NULL;

            }

            for(  int  i=0;  i<  m;  i++)

            {

                   scanf("%d%d",&x,&y);

                   build(x,y);

            }

            rank(n);  

    }

   return  0;

}

  

你可能感兴趣的:(HUD 1285 确定比赛名次)