您的位置:首页 > 其它

bfs别忘啊...UVA11624Fire!(BFS) 止めないで//车轮的bfs /UVA10047

2018-04-01 12:37 447 查看
四处搜罗来的...
然后这个代码书写习惯可真好 啊....
是bfs,但是大火这个需要些两次
有一个小坑,就是起火点可能会很多,所以不要只是记录一下起火点就好了,而是要把他们都push进去
然后一个个的往后蔓延...(是啊)
push进去的是时间为0的起火点....然后后面慢慢的就是时间为1的起火点....
(Map[nr][nc] == '.' || Map[nr][nc] == 'J') && nt<Time[nr][nc]

这个是火那边的【正是因为有了很多的起火点,才会发生这个地方更早就被火烧到了的惨案,只不过他们 的顺序可能排到后面了】
(这个时候进行的是更新)
并且在火的那个bfs里面,并没有使用vist数组,相当于时间判断也已经把vist取代了
火烧起来四个方向只要是可以的,都直接烧,直到烧到边界为止

逃跑的bfs里,因为只有一个人在逃跑,需要选取最短的最近的(而不是像火一样只是找到时间最短的就可以了)
所以这边还是要一个vist记录一下。。别的,不复杂= =
上代码....(别人的 我等下记几打一个交上去)#include <iostream>
#include <stdio.h>
#include <queue>
#include <string.h>
#define MAX 1010
using namespace std;

char Map[MAX][MAX];
int Time[MAX][MAX];
bool vis[MAX][MAX];
int r, c;
int dr[] = { -1,1,0,0 };
int dc[] = { 0,0,-1,1 };

struct P
{
int r, c, t;
P(int r_, int c_, int t_) :r(r_), c(c_), t(t_) {}
};
queue<P> F;
queue<P> J;

/**************Debug*************/
/*
void show_Time()
{
for (int i = 0; i<r; i++)
{
for (int j = 0; j<c; j++)
printf("%d ", Time[i][j]);
printf("\n");
}
}
*/

/*******************************/

void clear()
{
memset(vis, false, sizeof(vis));
while (!F.empty())
F.pop();
while (!J.empty())
J.pop();
}

bool judge(int nr, int nc)
{
return (nr >= 0 && nr<r&&nc >= 0 && nc<c);
}// if it is return true
// else return false;

bool ok(int nr, int nc)
{
return (nr == 0 || nr == r - 1 || nc == 0 || nc == c - 1);
}//if it is return true
//else return false;

void bfs_f()
{
int nr, nc, nt;
while (!F.empty())
{//相当于这个题已经把初始化给你初始化好了
//内核都一样的不是吗//
P f = F.front();
F.pop();
for (int i = 0; i<4; i++)
{
nr = f.r + dr[i];
nc = f.c + dc[i];
nt = f.t + 1;
if (judge(nr, nc))
{//nt<Time[nr][nc]这个是干啥
//1可以到达,就塞进去
//2 新的时间和已记录过的相比,
//怎么可能你之后塞进去的比之前塞进去的还小呢....这可是火啊
//如果当前能达到的比之前存着的还小,你就比他还要更佳,...
if ((Map[nr][nc] == '.' || Map[nr][nc] == 'J') && nt<Time[nr][nc])
{
F.push(P(nr, nc, nt));
Time[nr][nc] = nt;
}
}
}
}
}

int bfs_j()
{
int nr, nc, nt;
while (!J.empty())
{
P j = J.front();
J.pop();
if (ok(j.r, j.c))//啊.... (???? 如果到了最外边一圈儿...??
return j.t + 1;

for (int i = 0; i<4; i++)
{
nr = j.r + dr[i];
nc = j.c + dc[i];
nt = j.t + 1;
if (judge(nr, nc))
{
if (vis[nr][nc] == false && Map[nr][nc] == '.'&&nt<Time[nr][nc])
{
J.push(P(nr, nc, nt));
vis[nr][nc] = true;
}
}
}
}
return 0;
}

int main()
{
int T, t;
scanf("%d", &T);
while (T--)
{
clear();
scanf("%d%d", &r, &c);

for (int i = 0; i<r; i++)
{

scanf("%s", Map[i]);
for (int j = 0; j<c; j++)
{
Time[i][j] = 1000000007;//初始化....
if (Map[i][j] == 'J')
{
J.push(P(i, j, 0));
vis[i][j] = true;
}

else if (Map[i][j] == 'F')
F.push(P(i, j, 0));
}
}
bfs_f();
//show_Time();
if (t = bfs_j())
printf("%d\n", t);
else
printf("IMPOSSIBLE\n");
}
return 0;
}
出处:https://blog.csdn.net/wr132/article/details/45399337
另外.....bfs还有一个题不错的补上来好了= -  是zj写的示范代码
不知不觉时间过得好快...似乎不打就忘了一样= =
所以有一点别的.....#include<bits/stdc++.h>
using namespace std;

int beginx, beginy, endx, endy;
char a[30][30];
int vis[30][30][5][6];
//这个呢就是用啦记录状态的点了
const int dx[4]= { -1,0,1,0 };
const int dy[4]= {0, 1,0,-1};
struct node {
int x, y, c, d, t;
//Chushiha!
node(int a,int b,int c,int d,int e):x(a),y(b),c(c),d(d),t(e){}

};
queue<node>q;
int main()
{
int n, m; int casee = 0;
while (cin >> n >> m&&(m!=0&&n!=0)) {
if (casee != 0)
cout<<endl;
memset(a, 0, sizeof(a));
int i, j;
for ( i = 1; i <= n; i++)
{
for (j = 1; j <= m; j++)
{
cin >> a[i][j];//你自己看的出来才有鬼.....
//用dev强行debug?
//建立在对自己的代码有自信的基础上
if (a[i][j] == 'S') {
beginx = i; beginy = j;
}
if (a[i][j] == 'T')
{
endx = i; endy = j;

}// #和.其实完全不用再判断了诶...
}
}

while (!q.empty())q.pop();

q.push(node(beginx, beginy, 0, 0,0));
//vis[beginx][beginy][0][0] = 1;
//第一个塞进去
memset(vis,0, sizeof(vis));
bool flag = false;
int ans = -1;
while(!q.empty())
{
node head = q.front();
q.pop();

if (vis[head.x][head.y][head.c][head.d] != 0)continue;

vis[head.x][head.y][head.c][head.d] = head.t;
//int ans;
if (head.x == endx && head.y == endy &&!head.c)// head.c == 0)
{
ans = head.t;
flag = true;
break;
}

q.push(node(head.x, head.y, head.c, (head.d + 1) % 4, head.t + 1));

q.push(node(head.x, head.y, head.c, (head.d + 3) % 4, head.t + 1));

int x = head.x + dx[head.d];
int y = head.y + dy[head.d];
if (a[x][y]!='#'&&a[x][y]!=0) {

q.push(node(x, y, (head.c + 1) % 5, head.d, head.t + 1));
}

}cout << "Case #" << ++casee<<endl;
if(flag)
cout <<"minimum time = "<<ans<<" sec"<<endl;
else cout << "destination not reachable" << endl;
}
return 0;
}别太高估自己了= - ....
我觉得就算让我把之前的重新写一遍都还不一定写对......很可怕的
不熟练,意思懂了 写也写不出来
...

..真废柴啊!
反正,不管怎么说吧,总是会有一个 结构体的内核在里面的
.........
不然,要么bfs不能跑,要么不能记录
bfs要记录的,状态变化的.

要么二阶 \\ 要么这个 总是要记的\\\
【之前没反应过来的:其实这里面也有一点需要注意的】

读入的时候是读入了a[i][j],然后但是往后面跑的时候是用的start的那个状态,这个状态如何更替呢?不能只靠一个干巴巴的a[i][j],尤其是在面对坐标的时候,单单干巴巴的一个数值是没办法记录的!因为坐标需要往上下左右以及这边那边都扩展!
然而你用一个结构体的话就解决了,读入 的时候只需要a[i][j]这个干巴巴的数值和你的startx,但是之后跑的 时候就会方便很多了
根据start开始四个方向跑跑跑....
...

//奶牛那个题
vist是一定需要记的!!! 否则,根本跑不出去的啊!!!
否则就会越加越多...所以干啥都是有理由的/

不是奶牛..是轮子这个题,特殊化就是不是i 和j,而是按照方向往后跑的....
dx[head.d]
dy[head.d]
= .=原理是这样的,借助struct这些所有的状态都压进去
然后,借助vist把这些一单单清空...
变种的题,要会做哦(趴)
别的就没什么了吧
加油w
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: