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;
}