BFS/DFS
来源:互联网 发布:海阔天空 信乐团知乎 编辑:程序博客网 时间:2024/06/03 05:06
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
const int maxn=100;
bool biaoji[maxn][maxn]; // 访问标记
int map[maxn][maxn]; // 坐标范围
int dir[4][2]={0,1,0,-1,1,0,-1,0}; // 方向向量,(x,y)周围的四个方向
bool CheckEdge(int x,int y) // 边界条件和约束条件的判断
{
if(!biaoji[x][y] && ...) // 满足条件
return 1;
else // 与约束条件冲突
return 0;
}
void dfs(int x,int y)
{
biaoji[x][y]=1; // 标记该节点被访问过
if(map[x][y]==G) // 出现目标态G
{
...... // 做相应处理
return;
}
for(int i=0;i<4;i++)
{
if(CheckEdge(x+dir[i][0],y+dir[i][1])) // 按照规则生成下一个节点
dfs(x+dir[i][0],y+dir[i][1]);
}
return; // 没有下层搜索节点,回溯
}
int main()
{
return 0;
}
例如杭电1242题:
题目大意是,从起点走到目标点去,并且花的时间最少
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define max 205
char map[max][max];
long a[100000],step,sum,n,m,visited[max][max];
long directions[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
void DFS(int x,int y)
{
if(map[x][y] == 'r') a[sum++] = step;
else if(map[x][y] != '#')
{
for(int i = 0; i < 4; i++)
{
int tx, ty;
tx = x + directions[i][0];
ty = y + directions[i][1];
if( map[tx][ty] != '#' && tx>=1 && tx <= n && ty >= 1 && ty <= m && visited[tx][ty] == 0)
{
if(map[tx][ty] == 'x')
{
step ++;
}
step++;
visited[tx][ty] = 1;
DFS(tx, ty);
visited[tx][ty] = 0;
step--;
if(map[tx][ty] == 'x')
step--;
}
}
}
}
int main()
{
long i,j,x,y,min;
while(scanf("%ld%ld",&n,&m)>0)
{
memset(visited,0,sizeof(visited));
sum=0;
step=0;
min=max;
for(i=1;i<=n;i++)
{
getchar();
for(j=1;j<=m;j++)
{
scanf("%c",&map[i][j]);
if(map[i][j]=='a')
{
x=i;
y=j;
}
}
}
visited[x][y]=1;
DFS(x,y);
if(sum==0)
printf("Poor ANGEL has to stay in the prison all his life.\n");
else
{
for(i=0;i<sum;i++)
if(a[i]<min)
min=a[i];
printf("%ld\n",min);
}
}
return 0;
}
广度优先搜索
* @param Vs 起点
* @param Vd 终点
*/
bool BFS(Node& Vs, Node& Vd){
queue<Node> Q;
Node Vn, Vw;
int i;
//初始状态将起点放进队列Q
Q.push(Vs);
hash(Vw) = true;//设置节点已经访问过了!
while (!Q.empty()){//队列不为空,继续搜索!
//取出队列的头Vn
Vn = Q.front();
//从队列中移除
Q.pop();
while(Vw = Vn通过某规则能够到达的节点){
if (Vw == Vd){//找到终点了!
//把路径记录,这里没给出解法
return true;//返回
}
if (isValid(Vw) && !visit[Vw]){
//Vw是一个合法的节点并且为白色节点
Q.push(Vw);//加入队列Q
hash(Vw) = true;//设置节点颜色
}
}
}
return false;//无解
}
例如杭电1242题:
题目大意是,从起点走到目标点去,并且花的时间最少
#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <iostream>
#include <algorithm>
#define INF 100000
using namespace std;
int sx, sy, ex, ey, n, m;
char mp[1000][1000];
int visit[1000][1000]; //用来标记是否走过(0为没有走过 1为走过了)
int dx[4] = { 0,0,1,-1 }, dy[4] = { 1,-1,0,0 };
struct node //结构体
{
int x, y;
int step;
};
int f(int x,int y) //判断是否能走
{
if (x >= 0 &&x < n && y >= 0 && y < m && mp[x][y] !='#' && visit[x][y] == 0)return 1;
return 0;
}
int bfs()
{
memset(visit, 0, sizeof(visit)); //全部的点都设为未标记
queue<node> que;
node frist, second; //frist用来表示当前位置的点, second用来表示下一位置的点
frist.x = sx, frist.y = sy, frist.step = 0; //初始化,起点位置,步数设为0
visit[sx][sy] = 1; //把该点标记
que.push(frist); //把第一个点压入
while (!que.empty())
{
frist = que.front(); que.pop();
int x = frist.x, y = frist.y;
if (x == ex && y == ey) return frist.step; //到达目标位置时结束
for (int i = 0; i < 4; i++)
{
int xx = x + dx[i], yy = y + dy[i];
if (f(xx, yy))
{
second.x = xx, second.y = yy;
second.step = frist.step + 1;
if (mp[xx][yy] == 'x') second.step++; //题目要求特殊处理
que.push(second);
visit[xx][yy] = 1;
}
}
}
return -1;
}
int main()
{
while (scanf("%d%d", &n, &m) !=EOF)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
cin >> mp[i][j];
if (mp[i][j] == 'r') { sx = i; sy = j; }
if (mp[i][j] == 'a') { ex = i; ey = j; }
}
}
int ans = bfs();
if (ans == -1) printf("Poor ANGEL has to stay in the prison all his life.\n");
else printf("%d\n", ans);
}
return 0;
}
杭电2612 题目大意:两个人要到一个东西(这个东西可能有多个)的最短距离。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <iostream>
#include <algorithm>
#define INF 100000
using namespace std;
int sx, sy, ex, ey, n, m;
char mp[1000][1000];
int visit[1000][1000]; //用来标记是否走过(0为没有走过 1为走过了)
int dx[4] = { 0,0,1,-1 }, dy[4] = { 1,-1,0,0 };
int a[2][205][205]; //用来表示从起点到任一点的距离
int yx, yy, mx, my;
struct node //结构体
{
int x, y;
int step;
};
int f(int x,int y) //判断是否能走
{
if (x >= 0 &&x < n && y >= 0 && y < m && mp[x][y] !='#' && visit[x][y] == 0)return 1;
return 0;
}
void bfs(int sx,int sy,int k)
{
memset(visit, 0, sizeof(visit)); //全部的点都设为未标记
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
a[k][i][j] = INF;
}
}
queue<node> que;
node frist, second; //frist用来表示当前位置的点, second用来表示下一位置的点
frist.x = sx, frist.y = sy, frist.step = 0; //初始化,起点位置,步数设为0
a[k][sx][sy] = 0; //用来表示从起点到任一点的距离
visit[sx][sy] = 1; //把该点标记
que.push(frist); //把第一个点压入
while (!que.empty())
{
frist = que.front();
que.pop();
int x = frist.x, y = frist.y; //x、y分别是当前位置的横纵坐标
for (int i = 0; i < 4; i++)
{
int xx = x + dx[i], yy = y + dy[i];
if (f(xx, yy))
{
second.x = xx, second.y = yy;
a[k][xx][yy] = a[k][x][y] + 1;
visit[xx][yy] = 1;
que.push(second);
}
}
}
}
int main()
{
while (scanf("%d%d", &n, &m) !=EOF)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
cin >> mp[i][j];
if (mp[i][j] == 'Y') { yx = i; yy = j; }
if (mp[i][j] == 'M') { mx = i; my = j; }
}
}
bfs(yx, yy, 0);
bfs(mx, my, 1);
int minn = INF;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if (mp[i][j] == '@')
{
minn = min(minn, a[0][i][j] + a[1][i][j]);
}
}
}
minn = minn * 11;
cout << minn << endl;
}
return 0;
}
- BFS-DFS
- BFS DFS
- DFS+BFS
- BFS DFS
- DFS BFS
- DFS & BFS
- BFS,DFS
- dfs bfs
- BFS&DFS
- DFS BFS
- BFS && DFS
- BFS DFS
- DFS & BFS
- DFS&BFS
- BFS&DFS
- dfs && bfs
- dfs bfs
- BFS/DFS
- POJ
- 京东商品信息爬虫
- 系统销量统计
- text-shadow,box-shadow使用
- stack queue free-lock implate
- BFS/DFS
- <%@ taglib uri="" prefix=""%> 使用
- 了解log4j
- 域名来路判断
- List
- java redirect跳转
- String字符串的拼接问题
- java static
- CodeForces