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;
}

  

posted @ 2011-08-05 11:34  wutaoKeen  阅读(186)  评论(0编辑  收藏  举报