搜索与图论2
程序员文章站
2023-12-26 23:30:39
...
宽度优先搜索BFS
queue<int> q;
st[1] = true; // 表示1号点已经被遍历过
q.push(1);
while (q.size())
{
int t = q.front();
q.pop();
for (int i = h[t]; i != -1; i = ne[i])
{
int j = e[i];
if (!st[j])
{
st[j] = true; // 表示点j已经被遍历过
q.push(j);
}
}
}
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
const int N = 1e2 + 7;
int g[N][N], d[N][N];
int n, m;
int bfs() {
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
queue <PII> q;
for (auto &v : d)
for (auto &x : v) {
x = - 1;
}
d[0][0] = 0;
q.push({0, 0});
while (!q.empty()) {
auto t = q.front();
q.pop();
for (int i = 0; i < 4; i++) {
int x = t.first + dx[i], y = t.second + dy[i];
if (x >= 0 && x < n && y >= 0 && y < m && g[x][y] == 0 && d[x][y] == -1) {
d[x][y] = d[t.first][t.second] + 1;
q.push({x, y});
}
}
}
return d[n - 1][m - 1];
}
int main() {
cin >> n >> m;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> g[i][j];
}
}
cout << bfs() << endl;
return 0;
}
#include<stdio.h>
#include<queue>
#include<iostream>
using namespace std;
char maze[201][201];
int sx, sy, tx, ty;
//左右上下4个方向
int dx[4] = { 1,0,-1,0 };
int dy[4] = { 0,1,0,-1 };
int m, n;
struct node {
int x, y, dis;
};
bool operator < (const node & a, const node & b) {
return a.dis > b.dis;
}
void bfs() {
priority_queue<node> que;
node st { sx,sy,0 };
maze[sx][sy] = '#';
que.push(st);
while (!que.empty()) {
node p = que.top();
que.pop();
//若已找到,则退出
if (p.x == tx && p.y == ty) {
cout << p.dis << endl;
return;
}
for (int i = 0; i < 4; ++i) {
int nx = p.x + dx[i];
int ny = p.y + dy[i];
node np{ nx,ny, 0};
if (nx >= 0 && nx < n&&ny >= 0 && ny < m&&maze[nx][ny] != '#') {
if (maze[nx][ny] == 'X')
np.dis = p.dis + 2;
else
np.dis = p.dis + 1;
maze[np.x][np.y] = '#';
que.push(np);
}
}
}
printf("impossible\n");
}
int main() {
while (cin>>n>>m) {
for (int i = 0; i < n; i++)
scanf("%s", maze[i]);
for(int i=0; i<n; i++)
for (int j = 0; j < m; j++) {
if (maze[i][j] == 'S')
sx = i, sy = j;
else if (maze[i][j] == 'T')
tx = i, ty = j;
}
bfs();
}
return 0;
}
八数码
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
int fact[9];
bool vis[362880];
int permutation_hash(char s[]) //求长度为9的字符串某种排列的哈希值
{
int ans = 0;
for(int i = 0; i < 9; i ++)
{
int d = 0;
for(int j = 0; j < i; j ++)
if(s[j] > s[i]) d ++; //求s[i]与其前面的字符组成的逆序对个数
ans += d * fact[i];
}
return ans;
}
typedef struct{
char s[10];
int step;
int k; //'x'在第k位
}Point;
int dx[4] = {-1, 0, 1, 0};
int dy[4] = { 0,-1, 0, 1};
int bfs(Point p)
{
vis[permutation_hash(p.s)] = true;
queue<Point> q;
q.push(p);
while(!q.empty())
{
p = q.front();
q.pop();
/*
printf("%d ",p.step); //print调试法
puts(p.s);
*/
if(!strcmp(p.s , "12345678x")) return p.step;
int x = p.k / 3; //'x'的行数
int y = p.k % 3; //'x'的列数
Point next;
next.step = p.step + 1;
for(int i = 0; i < 4; i ++)
{
int nx = x + dx[i];
int ny = y + dy[i];
if(nx >= 0 && nx <= 2 && ny >= 0 && ny <= 2)
{
next.k = nx * 3 + ny; //求出'x'在字符串中的的新位置
strcpy(next.s, p.s);
next.s[9] = 0;
next.s[p.k] = p.s[next.k]; //先用即将和'x'交换的字符覆盖'x'之前的位置
next.s[next.k] = 'x'; //再给'x'的新位置赋值'x'
int hash = permutation_hash(next.s);
if(!vis[hash])
{
vis[hash] = true;
q.push(next);
}
}
}
}
return -1;
}
int main()
{
fact[0] = 1;
for(int i = 1; i < 9; i ++) fact[i] = fact[i - 1] * i; //预处理fact[i] = i!
char c[2],str[10];
Point start;
for(int i = 0; i < 9; i ++)
{
scanf("%s",&c);
if(c[0] == 'x') start.k = i;
start.s[i] = c[0];
}
start.s[9] = 0;
start.step = 0;
printf("%d",bfs(start));
return 0;
}