P3916 图的遍历 【反向建图+DFS】
题目
https://www.luogu.com.cn/problem/P3916
思路
要有建反向图的意识,当看到是一个点对多个点的操作的时候,我们要注意进行反向建边,由 原来的一个点可以到达的点中最大值改为 计算这个较大的点能到达哪些点
具体的实现方法就是先将题目中的点由大到小进行DFS遍历,在遍历的过程中记录,如果以及记录过的就不再记录,因为第一次记录的一定是最大值
代码
#include<iostream> #include<cstdio> using namespace std; #define maxn 100005 #define maxm 100005 struct node { int to; int next; }e[maxm]; int cnt = 0, head[maxn], vis[maxn],maxx[maxn]; int n, m; void addedge(int u, int v) { cnt++; e[cnt].to = v; e[cnt].next = head[u]; head[u] = cnt; } void dfs(int s,int d) { vis[s] = 1; for (int i = head[s]; i; i = e[i].next) { int y = e[i].to; if (vis[y])continue; maxx[y] = d; dfs(y,d); } } int main() { scanf("%d%d", &n, &m); for (int i = 0; i <= n; i++)maxx[i] = i; for (int i = 1; i <= m; i++) { int u, v; scanf("%d%d", &u, &v); addedge(v,u); } for (int i = n; i > 0; i--)dfs(i,i); for (int i = 1; i <= n; i++) printf("%d ", maxx[i]); }