题目链接:https://ac.nowcoder.com/acm/contest/46812/J
大致题意:给你一些大小关系,要你判断有些点是否可以判断他的具体位置。
易错点:将这个图用拓扑图的做法来思考,陷入思维漩涡。
正解:对每个点都进行两次dfs,一次正着进行,一次反着进行。对于一个点来说,如果到这个点的点的个数(正dfs)加上这个点能到的点的个数(反dfs)等于总点个数加一的话,则这个点的位置就确定下来了。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 1010,M = 1e5+10;
vector<int>eg[N],eg1[N];
int ans[N];
int cntd[N],cntx[N];
bool st[N];
void dfs1(int u,int s){
if (st[u]) return ;
st[u] = 1;
cntd[s]++;
for (int v:eg[u]) dfs1(v,s);
}
void dfs2(int u,int s){
if (st[u]) return ;
st[u] = 1;
cntx[s]++;
for (int v:eg1[u]) dfs2(v,s);
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,m;
cin>>n>>m;
for (int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
eg[x].push_back(y);
eg1[y].push_back(x);
}
for (int i=1;i<=n;i++){
memset(st,0,sizeof(st));
dfs1(i,i);
memset(st,0,sizeof(st));
dfs2(i,i);
//cout<<cntd[i]<<' '<<cntx[i]<<'\n';
}
for (int i=1;i<=n;i++){
if (cntd[i]+cntx[i]==n+1) ans[cntx[i]] = i;
}
for (int i=1;i<=n;i++){
if (ans[i]) cout<<ans[i]<<' ';
else cout<<-1<<' ';
}
return 0;
}
标签:dfs2,int,训练营,个数,dfs,st,牛客,2023,eg1
From: https://www.cnblogs.com/xjwrr/p/17268447.html