https://codeforces.com/contest/412/problem/D
这题为撒出线在dfs树的列表里。。。于是又是tarjan搞半天
对所有边建反边,然后强联通分量缩点后拓扑排序,然后还要处理一下强联通分量中的点的顺序,还挺麻烦的,我纠结到后面不想写了。。。
于是有更简单的做法。。。。直接建正边,由于u->v,u欠v钱,那u就不能再v前面一个位置。那么我们直接从一个点开始dfs,然后dfs到最底层后,回溯后,再输出当前节点,因为把u的所有欠钱的对象v都在前面输出过了,现在输出u肯定是没问题的。由于u->v不存在v->u,也就是不存在二元环,那么由于上一个输出的一定是u的某个直接儿子v,这个时候输出u,就是没问题的。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxl=3e5+10;
int n,m,cas,k,cnt,totc,totd,top,ind,ff;
int ans[maxl],rudu[maxl];
int s[maxl],dfn[maxl],low[maxl],f[maxl],sz[maxl];
bool in[maxl],vis[maxl];
vector<int> e[maxl];
inline void prework()
{
int u,v;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&u,&v);
e[u].push_back(v);
}
}
inline void dfs(int u)
{
vis[u]=true;
for(int v:e[u])
if(!vis[v])
dfs(v);
printf("%d ",u);
}
inline void mainwork()
{
for(int i=1;i<=n;i++)
if(!vis[i])
dfs(i);
}
inline void print()
{
}
int main()
{
int t=1;
//scanf("%d",&t);
for(cas=1;cas<=t;cas++)
{
prework();
mainwork();
print();
}
return 0;
}