FZU2150 广搜 两处点火

题目大意:

       点火,如何遍历所有的草坪,且时间最短。火不能经过空地。没有遍历全部的草坪输出-1

思路:枚举,bfs
        其中一个的位置先放在队列里面,另外一个暴力枚举就可以了。因为数据很小。



不过貌似我的这个代码是968MS,差点就TLE了,

具体的计算复杂度的话,就是bfs中有四个循环,one.size * n * m * (que.size * 4 * 2) 最大的话应该是O(100 * 100 * 800) 是800W吧。QAQ好险

本人新手,哪位大牛经过的话感觉可以优化请告诉我TAT



#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; typedef pair<int int=""> P; //上面这一行代码的pair中不知道为什么就乱码了,具体的是pair < int , int > 然后下面的小写p全都是大写的 const int inf = 0x3f3f3f3f; int n, m,cnt; char map[15][15];//0表示可走,1表示不可走 int step[15][15]; queue <p> que; queue </p><p> one; int dx[] = {0, 1, -1, 0}; int dy[] = {1, 0, 0, -1}; void work(P a){ for (int i = 0; i <= 3; i++){ int nx = a.first + dx[i], ny = a.second + dy[i]; if (map[nx][ny] == '#' && nx < n && nx >= 0 && ny < m && ny >= 0){ if (step[nx][ny] == -1){ step[nx][ny] = step[a.first][a.second] + 1; que.push(P(nx, ny)); } else if (step[nx][ny] >= 0 && step[nx][ny] > step[a.first][a.second] + 1){ step[nx][ny] = step[a.first][a.second] + 1; que.push(P(nx, ny)); } } } } int check(){ int res = -1; for (int i = 0; i < n; i++){ for (int j = 0; j < m; j++){ if (map[i][j] == '#' && step[i][j] == -1) return res = -1; if (map[i][j] == '#') res = max(res, step[i][j]); } } return res; } void bfs(){ int ans = -1; while (!one.empty()){//复杂度为O(1000^3) P tmp = one.front(); one.pop(); for (int i = 0; i < n; i++){ for (int j = 0; j < m; j++){ if (map[i][j] == '#'){ memset(step, -1, sizeof(step)); step[i][j] = 0; que.push(P(i, j)); while (!que.empty()){//第一团火的遍历 P a = que.front(); que.pop(); work(a); } que.push(tmp); step[tmp.first][tmp.second] = 0; while (!que.empty()){ P a = que.front(); que.pop(); work(a); } int k = check(); if (ans > -1 && k != -1){ ans = min(ans, k); } else if(ans == -1 && k != -1){ ans = k; } } } } } printf("Case %d: %d\n", ++cnt, ans); } int main(){ int t; scanf("%d", &t); getchar(); while (t--){ scanf("%d%d", &n, &m); while (!one.empty()) one.pop(); getchar(); for (int i = 0; i < n; i++){ for (int j = 0; j < m; j++){ scanf("%c", &map[i][j]); if (map[i][j] == '#') one.push(P(i, j)); } getchar(); } bfs(); } return 0; } </p></int></queue></algorithm></cstring></cstdio>

你可能感兴趣的:(FZU2150 广搜 两处点火)