题意:nXm的地图, 问通过四个方向从(1,1)走到(1000,1000)所经过的最小二进制序列是多少,忽略前缀0.
思路:首先如果起点为0,那么我们bfs搜索和起点0联通的为0的连通块,这样我们第一步肯定是从与这个连通块相邻的且与重点最近的地方出发。
将所有可能起点加入队列,在bfs一遍找到字典序最小的那条路就是答案,
在这里可以用两个vector类型容器,一个是q2存储所有节点值存为0的结点,
另一个q3存储节点值为1的结点。
那么如果q2不为空那么也就是有可以走零,那么就从这里面选,否则从q3中选。
ps:下午比赛时各种doubi,先是dfs无悬念超时....然后改成把求字典序的那个dfs改成了bfs结果re访问非法.......改了后结果爆栈.........最后改了一发觉得肯定对了然而mle了......
直到比赛结束也没发现为啥mle了,写了三个半小时要哭了..........回来后发现是因为最开始搜索连通块时我是每次访问结点时才置vis为1而不是每次添加结点时就置vis为1,这样每次会添加很多重复结点肯定会mle...........哭晕在厕所,本来可以ac的还是基础不扎实........任重道远
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
#define eps 1e-6
#define LL long long
using namespace std;
//const int maxn = 100 + 5;
//const int INF = 0x3f3f3f3f;
bool G[1005][1005];
bool vis[1005][1005];
const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, -1, 0, 1};
bool vis2[1005][1005];
vector<pair<short int, short int> > qq;
bool path[2005];
int leng;
int n, m;
void bfs2() {
queue<pair<short int, short int> > q;
q.push(make_pair(1, 1));
vis[1][1] = 1;
while(!q.empty()) {
pair<short int,short int> t = q.front(); q.pop();
int i = t.first, j = t.second;
for(int k = 0; k < 4; k++) {
int u = i + dx[k], v = j + dy[k];
if(u < 1 || u > n || v < 1 || v > m || vis[u][v]) continue;
if(G[u][v]) {
leng = min(leng, n+m-u-v+1);
continue;
}
q.push(make_pair(u, v));
vis[u][v] = 1;
}
}
}
vector<pair<short int, short int> > q2, q3;
void bfs() {
path[1] = 1;
int cnt = 1;
while(cnt < leng) {
q2.clear(); q3.clear();
int sz = qq.size();
for(int fuck = 0; fuck < sz; fuck++) {
pair<short int, short int> t = qq[fuck];
int i = t.first, j = t.second;
for(int k = 2; k < 4; k++) {
int u = i + dx[k], v = j + dy[k];
if(u < 1 || u > n || v < 1 || v > m || vis2[u][v]) continue;
else {
q2.push_back(make_pair(u, v));
if(!G[u][v]) q3.push_back(make_pair(u, v));
vis2[u][v] = 1;
}
}
}
cnt++;
if(q3.empty()) {
qq = q2;
path[cnt] = 1;
}
else {
path[cnt] = 0;
qq = q3;
}
}
}
char str[1005];
int main() {
// freopen("input.txt", "r", stdin);
int t; cin >> t;
while(t--) {
memset(vis, 0, sizeof(vis));
memset(vis2, 0, sizeof(vis2));
qq.clear();
cin >> n >> m;
for(int i = 1; i <= n; i++) {
scanf("%s", &str);
int len = strlen(str);
for(int j = 0; j < len; j++) {
if(str[j] == '1') G[i][j+1] = 1;
else G[i][j+1] = 0;
}
}
leng = n + m - 1;
if(!G[1][1]) bfs2();
//cout << leng << endl;
if(!G[1][1]) for(int i = 1; i <= n; i++) {
int j = n + m - leng + 1 - i;
if(j > m || j < 1) continue;
if(!G[i][j]) continue;
for(int k = 0; k < 2; k++) {
int u = i + dx[k], v = j + dy[k];
if(u < 1 || u > n || v < 1 || v > m || !vis[u][v]) continue;
else {
qq.push_back(make_pair(i, j));
// cout << i << " " << j << endl;
vis2[i][j] = 1;
break;
}
}
}
else qq.push_back(make_pair(1, 1)), vis2[1][1] = 1;
if(!vis[n][m]) {
bfs();
for(int i = 1; i <= leng; i++) printf("%d", path[i]);
}
else printf("0");
puts("");
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
HDU 5335 Walk Out(Bfs搜索字典序最小的最短路)
原文地址:http://blog.csdn.net/u014664226/article/details/47159301