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