萌新求助
查看原帖
萌新求助
234783
conprour楼主2021/11/18 22:46

有一种不一样的想法:

1-n枚举起点

把每个点的出边从小到大排序

从起点往下走,走完所有出边,回溯的时候把起点加入答案(就是DFS

相当于一条路走到底,从底层往上加入答案 (没考虑impossible)

0pts WA,为什么?(过了样例)

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define FCC fclose(stdin),fclose(stdout)
const int INF = 0x3f3f3f3f,N = 1e5+10,M = N;
inline ll read()
{
	ll ret=0;char ch=' ',c=getchar();
	while(!(c>='0'&&c<='9')) ch=c,c=getchar();
	while(c>='0'&&c<='9') ret=(ret<<1)+(ret<<3)+c-'0',c=getchar();
	return ch=='-'?-ret:ret;
}
int n,m;
int tot,oud[N];

int ans[N];
bool vis[N];
vector<int> G[N];
void dfs(int u,int fa)
{
	if(vis[u]) return;
	for(int i=0;i<(signed)G[u].size();i++)
	{
		int v=G[u][i];
		if(v==fa) continue;
		dfs(v,u);
		if(vis[v]) oud[u]--;
	}
	if(!oud[u]) ans[++tot]=u,vis[u]=1;
}
void init_edge(){
	for(int i=1;i<=n;i++) G[i].clear(),oud[i]=vis[i]=0;
	tot=0;
}
void work()
{
	n=read(),m=read();
	init_edge();
	for(int i=1;i<=m;i++) 
	{
		int u=read(),v=read();
		G[v].push_back(u);
		oud[v]++;
	}
	for(int i=1;i<=n;i++)
		sort(G[i].begin(),G[i].end());
	for(int i=1;i<=n;i++) 
		if(!vis[i]) dfs(i,0);
	for(int i=1;i<=tot;i++) printf("%d ",ans[i]);
	puts("");
}
int main()
{
	int T=read();
	while(T--) work(); 
	return 0;
}
/*
2
5 4
5 4
5 3
4 2
3 2
5 2
5 2
4 3
*/
2021/11/18 22:46
加载中...