DFS(深度优先搜索)
一种用于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过或者在搜寻时结点不满足条件,搜索将回溯到发现节点v的状态。整个进程反复进行直到所有节点都被访问为止。在没有进行剪枝的情况下,DFS=暴力搜索,**时间复杂度可达O(n!)或以上**。
题目:全排列问题 - 洛谷
题解:
#include<bits/stdc++.h>
using namespace std;
int n,a[10],q[50000],v[10],p;
void dfs(int step)
{
if(step==n+1)//第n+1步时,表示已经选择了n个数
{
for(int i=1; i<=n; i++)//进行输出
{
printf("%5d",q[i]);//%5d是保留五个场宽
}
cout << '\n';
return;
}
for(int i=1; i<=n; i++)
{
if(v[i]==0)
{
q[step]=i;
v[i]=1;
dfs(step+1);
v[i]=0;
}
}
return ;
}
int main()
{
cin >>n;
dfs(1);
return 0;
}
(取材于某位大神)
题目:迷宫 - 洛谷
题解:
#include<bits/stdc++.h>
using namespace std;
int n,m,t,a[10][10],v[10][10],ans;
int d[][2]={{0,1},{1,0},{0,-1},{-1,0}};
struct point
{
int x,y;
};
point start,fi;
void dfs(point s)
{
point temp;
if(s.x==fi.x&&s.y==fi.y)
{
ans++;
return;
}
for(int i=0;i<4;i++)
{
temp.x=s.x+d[i][1];
temp.y=s.y+d[i][0];
if(temp.y>=1&&temp.y<=n&&temp.x>=1&&temp.x<=m&&a[temp.y][temp.x]==0&& v[temp.y][temp.x]==0)
{
v[temp.y][temp.x]=1;
dfs(temp);
v[temp.y][temp.x]=0;
}
}
return;
}
int main()
{
cin >> n >> m>> t;
cin >> start.y >> start.x >> fi.y >> fi.x;
point temp;
for(int i=0;i<t;i++)
{
cin >> temp.y >> temp.x;
a[temp.y][temp.x]=1;
}
v[start.y][start.x]=1;
dfs(start);
cout << ans;
return 0;
}
( 取材于某位大神)
BFS(广度优先搜索)
同样是一种遍历搜索树或图的算法。遍历方式为选定一个节点,接着访问所有与当前节点连接的满足条件的点。接着从这些可访问点中,按照相同的遍历方式访问每个节点,直到所有节点都被访问,这与树的层次遍历相同,时间复杂度与DFS相同,与搜索树和图的节点树相关。**BFS一般用于解决最短路径,最短步骤等最优问题。
题目:离开中山路 - 洛谷
题解:
#include <bits/stdc++.h>
using namespace std;
int a, b, c, d, n, vis[1005][1005];
int dc[] = {0, 0, -1, 1};
int dr[] = {-1, 1, 0, 0};
char s[1005][1005];
struct point
{
int c, r, step;
};
int bfs(point start)
{
queue<point> q;
q.push(start);
vis[start.r][start.c] = 1;
while (!q.empty())
{
point front = q.front(),p;
q.pop();
for (int i = 0; i < 4; i++)
{
p.r = front.r + dr[i];
p.c = front.c + dc[i];
p.step = front.step + 1;
if (p.r >= 0 && p.r <= n && p.c >= 0 && p.c <= n && s[p.r][p.c] == '0' && vis[p.r][p.c] == 0)
{
vis[p.r][p.c] = 1;
q.push(p);
}
if (p.r == c && p.c == d)
{
return p.step;
}
}
}
return 0;
}
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
cin >> s[i][j];
}
}
cin >> a >> b >> c >> d;
point s;
s.r = a;
s.c = b;
s.step = 0;
cout << bfs(s);
return 0;
}
(取材于某位大神)
题目:奇怪的电梯 - 洛谷
题解:
#include<bits/stdc++.h>
using namespace std;
int n,a,b,s[205],visited[205];
struct node
{
int id,step;
};
int bfs(node start)
{
queue<node> q;
q.push(start);//将起始楼层入队
visited[start.id]=1;//标记楼层
while (!q.empty())
{
node front=q.front(),down,up;//获取现在所在楼层的状态
down.id=front.id-s[front.id];//当前楼层向下可到达的楼层
up.id=front.id+s[front.id];//当前楼层向上课到达的楼层
down.step=front.step+1;//步数加一
up.step=front.step+1;
if (front.id==b)//如果当前楼层为目标楼层,返回结果
{
return front.step;
}
if (down.id>=1 && visited[down.id]==0)//判断当前楼层向上是否是可达的
{
visited[down.id]=1;
q.push(down);//入队
}
if (up.id<=n && visited[up.id]==0)//与上相同
{
visited[up.id]=1;
q.push(up);
}
q.pop();//在遍历了所有可能后,将队首元素出队
}
return -1;
}
int main()
{
cin >> n >> a >> b;
for (int i = 1; i <= n; i++)
{
cin >> s[i];
}
node s;
s.id=a;
s.step=0;
cout << bfs(s);
return 0;
}
(取材于某位大神)
(图片取自网络)