文章目录
DFS专题
1.小朋友崇拜圈(拓扑排序 + dfs图的遍历)
题意:找最大的圈(环),输出结果。
思路:一个环中每一个点的入度至少为1,那么入度为0的点不可能构成环,因此拓扑排序将入度为1的点去掉,然后dfs遍历得到每一个环的大小,去最值即可。
【代码实现】
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 1e5 + 10, M = 2 * N;
int h[N], e[M], ne[M], idx;
int d[N];// 统计入度情况
bool st[N];
int a[N];
int n;
void add(int a, int b) // 添加一条边a->b
{
e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}
void topsort()
{
queue<int> q;
for (int i = 1; i <= n; i ++ )
if(d[a[i]] == 0)
q.push(i);
while(q.size())
{
auto t = q.front();
q.pop();
for(int i = h[t]; i != -1; i = ne[i])
{
int j = e[i];
d[j] --;
if(d[j] == 0)
q.push(j);
}
}
}
// int dfs(int u, int father, int sum)
// {
// if(st[u]) return cnt;
// st[u] = true;
// sum ++;
// for(int i = h[u]; i != -1; i = ne[i])
// {
// int j = e[i];
// if(j == father) continue;
// return dfs(j, u, sum);
// }
// }
// 下面这个dfs函数在acwing能过,蓝桥杯官网报的编译错误(我不理解)
int dfs(int u, int father)
{
st[u] = true;
int sum = 1;
for(int i = h[u]; i != -1; i = ne[i])
{
int j = e[i];
if(!st[j])
{
int s = dfs(j, u);
sum += s;
}
}
return sum;
}
int main()
{
cin >> n;
memset(h, -1, sizeof h);
for (int i = 1; i <= n; i ++ )
{
cin >> a[i];
d[a[i]] ++;
add(i, a[i]);
}
topsort();
int ans = -1e8;
for (int i = 1; i <= n; i ++ )
{
if(d[i] && !st[i])// 度不为0且没被访问过
{
int tmp = dfs(i, -1);
// cout << tmp << endl;
ans = max(ans, tmp);
}
}
// puts("");
cout << ans;
return 0;
}
2.路径之迷(dfs + 路径打印)
【题目链接】https://www.lanqiao.cn/problems/89/learning/
搜索每一个由起点走到终点的所有路线,经过每一个位置时,给它的x、y都加上1的贡献,最后到达右下角时,如果x、y的值等于输入的箭靶的数目则为正确答案
【代码实现】
只得了一部分分数(40%)
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
const int N = 25;
int g[N][N];
int rx[N], ry[N];
int nx[N], ny[N];
vector<int> path;
bool st[N][N];
bool is_find;
int n;
int dx[4] = {
-1, 0, 1, 0}, dy[4] = {
0, 1, 0, -1};
bool check()
{
for (int i = 0; i < n; i ++ )
if(rx[i] != nx[i] || ry[i] != ny[i])
return false;
return true;
}
void dfs(int x, int y)
{
if(is_find) return ;// 结束递归
if(x == n - 1 && y == n - 1 && check())
{
// if(check())
// {
is_find = true;
for (int i = 0; i < path.size(); i ++) cout << path[i] << ' ';
// }
return ;
}
for(int i = 0; i < 4; i ++)
{
int a = x + dx[i], b = y + dy[i];
if(a < 0 || a >= n || b < 0 || b >= n) continue;
if(st[a][b]) continue;
st[a][b] = true;
rx[a] ++;
ry

最低0.47元/天 解锁文章
399

被折叠的 条评论
为什么被折叠?



