【问题描述】
此题为ACM竞赛真题,更强大的测试数据请自行前往以下链接进行代码提交验证。Problem - 1285 (hdu.edu.cn)
有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队。
【输出形式】
给出一个符合要求的排名。输出时队伍号之间有空格,最后一名后面没有空格。
【样例输入】
4 3
1 2
2 3
4 3
【样例输出】
1 2 4 3
【样例说明】
符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前;输入数据保证是正确的,即输入数据确保一定能有一个符合要求的排名。
#include<iostream>
#define maxsize 10
using namespace std;
int n;//队伍数量
int m;//胜负关系数量
int visit[maxsize];//用于记录队伍是否访问过
int indegree[maxsize];//每只队伍的入度
int g[maxsize][maxsize];//关系矩阵
void initMatrix()//初始化关系矩阵
{
for (int i = 1; i <= m; i++)
{
int v1, v2;
cin >> v1 >> v2;
if (g[v1][v2] == 0)
{
g[v1][v2] = 1;
indegree[v2]++;
}
}
}
int getMin()//找出所有顶点中入度为0且序数最小的
{
int ans = 99;
for (int i = 1; i <= n; i++)
{
if (!visit[i] && indegree[i] == 0 && i<ans)
{
ans = i;
}
}
return ans;
}
bool isAllVisit()//判断是否全部的队伍都被选择
{
for (int i = 1; i <= n; i++)
{
if (visit[i] == 0)
{
return false;
}
}
return true;
}
void topoLogicalSort()
{
while (!isAllVisit())
{
int e = getMin();
if (e)
{
cout << e << " ";
visit[e] = 1;
for (int i = 1; i <= n; i++)
{
if (g[e][i] == 1)
{
indegree[i]--;
}
}
}
}
}
int main()
{
cin >> n >> m;
fill(visit, visit + maxsize, 0);
fill(indegree, indegree + maxsize, 0);
fill(g[0], g[0] + maxsize * maxsize, 0);
initMatrix();
topoLogicalSort();
//system("pause");
return 0;
}