2023年牛客基础训练营4-J

题目链接: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;
}
posted @ 2023-03-29 12:08  安潇末痕  阅读(32)  评论(0)    收藏  举报