基本思路:算出各个元素的入度,当入度为0时输出即可,在输出入度为0的元素时,通过循环操作来找出此元素之前的元素,并使这些元素的入度减1,直到为0便可输出。
例题:
ACM排位赛
Time Limit: 2000/1000ms (Java/Others)
Problem Description:
在某一天大大们决定举行一次ACM排位比赛,检验一下各位ACMer的学习成果,并在某天举行了比赛。参与比赛的有N个ACMer(1<=N<=500), 他们的编号依次为1,2,3,...,N。比赛结束后,大大们想要将所有参赛的ACMer从前往后依次排名,然而由于大大们非常的怠工不想直接 获得每个ACMer的比赛成绩,现在只知道ACMer两两之间的的排名先后,即 A1比A2通过的题目要多,用(A1,A2)表示,排名时A1在A2之前。 现在大大决定甩锅给你,请你确定ACMer们的排名。
Input:
输入有若干组,每组中的第一行为二个数N(1<=N<=500),M;其中N表示队伍的个数, M表示接着有M行的输入数据。接下来的M行数据中,每行也有两个整数(A1,A2)表示即A1刷的题比A2多。
Output:
给出一个符合要求的排名。输出时两个数据之间有空格,数据输出结尾没有多余的空格。 说明:符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前; 输入数据保证是正确的,即输入数据确保一定能有一个符合要求的排名。
Sample Input:
4 3 1 2 2 3 4 3
Sample Output:
1 2 4 3
AC代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int tu[555][555];
int num[555];
int ans[555];
int n,m;
void topsort()
{
int sum = 0;
priority_queue <int,vector<int>,greater<int> >pq;
for(int i = 1;i <= n;i++)
if(num[i] == 0)
pq.push(i);
while(!pq.empty())
{
int x = pq.top();
ans[sum++] = x;
pq.pop();
for(int i = 1;i<=n;i++)
if(tu[x][i] == 1)
{
num[i]--;
if(num[i] == 0)
pq.push(i);
}
}
cout << ans[0] ;
for(int i = 1;i < sum;i++)
cout << ' ' <<ans[i] ;
cout << endl;
}
int main()
{
while(cin >> n >>m)
{
memset(tu,0,sizeof(tu));
memset(num,0,sizeof(num));
int x,y;
while(m--)
{
cin >> x >> y;
tu[x][y] = 1;
num[y]++;
}
topsort();
}
return 0;
}