折腾了一下午,一开始以为从1....n分别找出反向路径进行输出,然后就是正确的姿势了,提交了一两把,发现是错的,比如下面的case:
4 3
4 2
2 1
3 1
4 3
4 2
2 1
3 1
正解应该是4 2 3 1, 而我的是3 4 2 1,后面的2的位置明显靠后,然后看了想了一下符合反向拓扑排序的规律,所以建边的时候反着建就可以了。
当然输出也要是逆向的,这个时候借助一下栈就可以了。
#include "stdio.h"
#include "string.h"
#include "math.h"
#include <string>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <algorithm>
#include <iostream>
using namespace std;
#define MAX 100005
#define max(a,b) a > b ? a : b
#define min(a,b) a < b ? a : b
#define abs(a) a < 0 ? a : (-a)
#define Mem(a,b) memset(a,b,sizeof(a))
int Mod = 1000000007;
double pi = acos(-1.0);
double eps = 1e-6;
typedef struct{
int f,t,next;
}Edge;
Edge edge[MAX];
int head[MAX];
int indree[MAX];
int kNum;
void addEdge(int f, int t)
{
edge[kNum].f = f;
edge[kNum].t = t;
edge[kNum].next = head[f];
head[f] = kNum ++;
}
int T, n, m;
void solve()
{
Mem(head, -1);
Mem(indree, 0);
int u,v;
kNum = 0;
priority_queue<int, vector<int>, less<int>> q; //小到大
stack<int> ans;
for(int i = 0; i < m; i ++){
scanf("%d %d",&u, &v);
addEdge(v,u);
indree[u] ++;
}
for(int i = 1; i <= n; i ++){
if( indree[i] == 0 )
q.push(i);
}
while( !q.empty() ){
int t = q.top();
ans.push(t);
q.pop();
for(int k = head[t]; k != -1; k = edge[k].next){
indree[edge[k].t] --;
if( indree[edge[k].t] == 0 )
q.push(edge[k].t);
}
}
bool flag = true;
while( !ans.empty() ){
if( flag ){
flag = false;
printf("%d",ans.top());
}
else
printf(" %d",ans.top());
ans.pop();
}
printf("\n");
}
int main()
{
// freopen("d:\\test.txt", "r", stdin);
while(cin>>T){
while( T-- ){
cin>>n>>m;
solve();
}
}
return 0;
}