洛谷p3916图的遍历题解

题面

思路:

反向建边,dfs艹咋想出来的啊

倒着遍历,如果你现在遍历到的这个点已经被标记了祖先是谁了

那么就continue掉

因为如果被标记了就说明前面已经遍历过了

而我们的顺序倒着来的

前边的一定比现在的大

所以continue掉

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int N = 100010;
int n, m, head[N], cnt, ans[N];
struct node{
    int nxt, to;
}e[N];
int read() {
    int s = 0, w = 1;
    char ch = getchar();
    while(!isdigit(ch)) {if(ch == '-') w = -1;ch = getchar();}
    while(isdigit(ch)) {s = s * 10 + ch - '0';ch = getchar();}
    return s * w;
}
void add(int x, int y) {
    e[++cnt].nxt = head[x];
    e[cnt].to = y;
    head[x] = cnt;
}
void dfs(int x, int fa) {
    ans[x] = fa;
    for(int i = head[x]; i; i = e[i].nxt)
        if(!ans[e[i].to]) dfs(e[i].to, fa);
}
int main() {
    n = read(), m = read();
    for(int i = 1; i <= m; i++) {
        int x, y;
        x = read(), y = read();
        add(y, x);
    }
    for(int i = n; i >= 1; i--) {
//        memset(vis, 0, sizeof(vis));
//        maxn = i;
        if(ans[i]) continue;
        dfs(i, i);
//        printf("%d\n", maxn);
    }
    for(int i = 1; i <= n; i++) printf("%d ", ans[i]);
    return 0;
}

谢谢收看, 祝身体健康!

猜你喜欢

转载自www.cnblogs.com/yanxiujie/p/11674367.html