题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1285
题意:共N个队伍,给出M个比赛结果,即u和v比赛,u胜v。求最终的比赛名次,若无法确定优先的,队伍号小的优先。
思路:裸拓扑排序。
拓扑排序:每次取入度为0的点为优先的点,取出后,删除该点所连接的边,重复操作直至所有点取完。
代码:(队列维护可能快一些?)
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <queue>
using namespace std;
const int N = 5e2 + 10;
int edge[N][N];
int in[N];
int n, m;
int main() {
while (scanf("%d%d", &n, &m) != EOF) {
memset(edge, 0, sizeof(edge));
memset(in, 0, sizeof(in));
for (int i = 0; i < m; i++) {
int u, v;
scanf("%d%d", &u, &v);
edge[u][v]++;
in[v]++;
}
bool first = true;
for (int i = 0; i < n; i++) {
int ind = -1;
for (int j = 1; j <= n; j++) {
if (in[j] == 0) {
ind = j;
break;
}
}
if (ind != -1) {
if (first)
first = false;
else
printf(" ");
printf("%d", ind);
in[ind] = -1;
for (int j = 1; j <= n; j++) {
if (edge[ind][j]) {
in[j] -= edge[ind][j];
}
}
}
else {
return -1;
}
}
printf("\n");
}
return 0;
}