题意:你懂得。。。
析:先说一下什么是拓扑排序,就比如这个题,是u赢了v,把“赢了”关系看成是一条有向边,那么就得到了个有向图。
那么这个题就转化成了,把一个图的所有结点排序,使得每一条有向边(u,v)对应的u都排在v前面。并且字典序最小。
这样的问题,就称为拓扑排序。
首先先构造出一个图来,考虑每一个入度,和有向边,然后进行拓扑排序。
要遍历n次,每次找出入度为0的,然后输出,然后把相关的边去掉,继续查找。直到结束。
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 500 + 10;
int in[maxn], t;
int G[maxn][maxn], n;
void toposort(){
for(int i = 1; i <= n; ++i){ //遍历n次,每次找出一个入度为0的节点
for(int j = 1; j <= n; ++j){
if(!in[j]){//找出入度为0的节点
--in[j];//改变值,以防再次被找到
if(i == n) printf("%d
", j);
else printf("%d ", j);
for(int k = 1; k <= n; ++k)
if(G[j][k]) --in[k];//把与之相关的全改掉
break;
}
}
}
}
int main(){
int m;
while(~scanf("%d %d", &n, &m)){
int x, y;
memset(G, 0, sizeof(G));
memset(in, 0, sizeof(in));
for(int i = 0; i < m; ++i){
scanf("%d %d", &x, &y);
if(!G[x][y]){//一定要判重边啊,不然会一直WA
G[x][y] = 1;
++in[y];
}
}
toposort();
}
return 0;
}