题干:
有N个比赛队(1<=N<=500),编号依次为1,2,3,。。。。,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比赛的结果,即P1赢P2,用P1,P2表示,排名时P1在P2之前。现在请你编程序确定排名。
Input
输入有若干组,每组中的第一行为二个数N(1<=N<=500),M;其中N表示队伍的个数,M表示接着有M行的输入数据。接下来的M行数据中,每行也有两个整数P1,P2表示即P1队赢了P2队。
Output
给出一个符合要求的排名。输出时队伍号之间有空格,最后一名后面没有空格。
其他说明:符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前;输入数据保证是正确的,即输入数据确保一定能有一个符合要求的排名。
Sample Input
4 3
1 2
2 3
4 3
Sample Output
1 2 4 3
解题报告:
拓扑排序模板。用邻接矩阵存图,会超时。
AC代码:
#include<bits/stdc++.h>
using namespace std;
const int MAX = 500 + 5 ;
struct Node {
int to;
int w;
int ne;
} e[MAX];
int in[MAX],head[MAX],ans[MAX];
int cnt = 0,top = 0;
priority_queue<int,vector<int > ,greater<int> > pq;
void init() {
cnt = 0;top = 0;
memset(in,0,sizeof(in));
memset(head,-1,sizeof(head));
while(!pq.empty() ) pq.pop();
}
void add(int u,int v,int w) {
e[cnt].to = v;
e[cnt].w = w;
e[cnt].ne = head[u];
head[u] = cnt;
cnt++;
}
int main()
{
int n,m;
int u,v;
while(~scanf("%d%d",&n,&m) ) {
init();
while(m--) {
scanf("%d%d",&u,&v);
add(u,v,0);
in[v]++;
}
//预处理一下pq
for(int i = 1; i<=n; i++) {
if(in[i] == 0 ) pq.push(i);
}
while(!pq.empty() ) {
int cur = pq.top();//养成习惯,bfs中也是,取出元素后都先给一个变量cur存着以免以后忘了pop,并且新的都用new表示
pq.pop();
ans[++top] = cur;
for(int i = head[cur]; i!=-1; i=e[i].ne) {
in[e[i].to]--;
if(in[e[i].to] == 0) pq.push(e[i].to);
}
}
if(top != n ) printf("不成环\n");
else {
for(int i = 1; i<=top; i++) {
printf("%d%c",ans[i],i==top?'\n':' ');
}
}
}
return 0 ;
}
超时代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
//struct Edge {
// int to;
// int w;
// int ne;
//
//} e[5000];
int maze[505][505];
int in[505];
void init() {
memset(in,0,sizeof(in));
memset(maze,0,sizeof(maze) ) ;
}
int main()
{
int n,m,u,v;
int flag = 0;
while(~scanf("%d%d",&n,&m) ) {
init();
while(m--) {
scanf("%d%d",&u,&v);
maze[u][v] = 1;
in[v]++;
}
int cnt = 0 ;
while(1) {
if(cnt == n) break;
flag = 0 ;
for(int i = 1; i<=n; i++) {
if(in[i] == 0) {
in[i]--;
if(cnt == n-1) {
printf("%d\n",i);
cnt++;
}
for(int j = 1; j<=n; j++) {
if(maze[i][j] == 1) {
flag = 1;
in[j]--;
maze[i][j] = 0;
cnt++;
printf("%d%c",i,cnt==n?'\n':' ');
break;
}
}
if(flag == 1) {
break;
}
}
}
}
}
return 0 ;
}