拓扑排序:在由一个有向无环图的顶点组成的序列中,当满足:
1、每个顶点出现且只出现一次;
2、若A在序列中排在B的前面,则在图中不存在从B到A的路径。那么就称该序列是该图的一个拓扑排序。
解题思路:当p1战胜p2的时候那么p2的前驱就是p1,p2前驱的数量就增加1。用一个数组
indegree[](初始化为0)
来存储每个点
的
前驱数量;前驱为0的自然就是第一名。找到第一名后输出,然后再把第一名删除掉,其余前驱相应减一,这时第二名就变成了第一名,以此类推。。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int map[505][505];//判断两支队伍是否进行了比赛
int n,indegree[505];//记录该队伍的前驱个数
int queue[505];//记录所有队伍的排名
void tuopu(){
int top;//暂存当前第一名
int k=0;//用来记录名次
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(indegree[j]==0){
top=j;//入度(前驱)为0的点即第一名
break;
}
}
queue[k++]=top;//保存当前第一名后,下一个“第一”就是K+1
indegree[top]=-1;//第一名入保存后,删除
for(int j=1;j<=n;j++){
if(map[top][j])
indegree[j]--;//每一项的入度都相应-1
}
}
for(int i=0;i<n-1;i++)
printf("%d ",queue[i]);
printf("%d\n",queue[n-1]);//输出格式
}
int main(){
int a,b,m;
while(~scanf("%d%d",&n,&m)){
memset(indegree,0,sizeof(indegree));
memset(map,0,sizeof(map));
for(int i=0;i<m;i++){
scanf("%d%d",&a,&b);
if(map[a][b]==0){//这个判断是为了防止数据中有重复!
map[a][b]=1;//记录对战的队伍
indegree[b]++;//战败队伍的入度+1
}
}
tuopu();
}
return 0;
}