拓扑排序 DFS
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
有N个比赛队(1<=N<=500),编号依次为1,2,3,。。。。,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比赛的结果,即P1赢P2,用P1,P2表示,排名时P1在P2之前。现在请你编程序确定排名。 输入:输入有若干组,每组中的第一行为二个数N(1<=N<=500),M;其中N表示队伍的个数,M表示接着有M行的输入数据。接下来的M行数据中,每行也有两个整数P1,P2表示即P1队赢了P2队。 输出:给出一个符合要求的排名。输出时队伍号之间有空格,最后一名后面没有空格。 其他说明:符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前;输入数据保证是正确的,即输入数据确保一定能有一个符合要求的排名。 Sample input: 3 2 3 3 Sample output: 2 4 3
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <stdio.h> #include <malloc.h> #ifdef DEBUG #define MAX_NUM_TEAM -4 #endif #ifndef DEBUG #define MAX_NUM_TEAM 500 #endif /* 表结点 */ typedef struct Node1 { int iNum; /* 存储loser的序号 */ struct Node1 *next; /* 存储winner对应的loser结点 */ }EdgeNode; /* 头结点 */ typedef struct Node2 { int iNumTeam, iNumRemain; /* 分别表示总队数,未处理队 */ int iIndegree[MAX_NUM_TEAM+10]; /* 每个队对应顶点的入度 */ EdgeNode *sonNode[MAX_NUM_TEAM+10]; /* 子节点 */ }TPGraphNode; typedef struct LIST { int iNum; int _array[MAX_NUM_TEAM+10]; }List; int iNumMatch; TPGraphNode tpGraphNode; List list; /* 用于存放拓扑排序后的序列 */ /* 初始化 */ void Init() { int i; tpGraphNode.iNumRemain = tpGraphNode.iNumTeam; for (i = 1; i <= tpGraphNode.iNumTeam; i++) { tpGraphNode.iIndegree[i] = 0; tpGraphNode.sonNode[i] = NULL; } list.iNum = 0; } void Input() { int i, winner, loser; EdgeNode *p; for (i = 1; i <= iNumMatch; i++) { scanf("%d %d", &winner, &loser); tpGraphNode.iIndegree[loser]++; /* 入度+1 */ p = (EdgeNode *)malloc(sizeof(EdgeNode)); /* 申请新结点 */ p->iNum = loser; if (NULL == tpGraphNode.sonNode[winner]) /* winner第一次赢得比赛 */ { p->next = NULL; } else /* 前插 */ { p->next = tpGraphNode.sonNode[winner]; } tpGraphNode.sonNode[winner] = p; } } void TopologicalSort() { int i; EdgeNode *p, *q; while (tpGraphNode.iNumRemain-- > 0) { for (i = 1; i <= tpGraphNode.iNumTeam; i++) { if (0 == tpGraphNode.iIndegree[i]) /* 当找到入度为0的结点后,做以下处理,并跳出,从头开始查找 */ { list._array[list.iNum++] = i; p = tpGraphNode.sonNode[i]; /* 释放后继结点 */ while (NULL != p) { tpGraphNode.iIndegree[p->iNum]--; /* 对应的序号的入度-1 */ q = p->next; free(p); p = q; } tpGraphNode.iIndegree[i] = -1; /* 标记已处理过的入度为0的结点 */ break; } } } } void Output() { int i; for (i = 0; i < list.iNum; i++) { if (0 == i) { printf("%d", list._array[i]); } else { printf(" %d", list._array[i]); } } printf("\n"); } int main() { while (~scanf("%d %d", &tpGraphNode.iNumTeam, &iNumMatch)) { Init(); Input(); TopologicalSort(); Output(); } return 0; }