FZU2150(双起点bfs->多起点)

题目大意:
给出一个height*width的图,'#'表示草坪,'.'表示空地,然后可以选择在任意的两个草坪格子点火,火每 1 s会向周围四个格子扩散,问选择那两个点使得燃烧所有的草坪花费时间最小?
大致思路:
重点是和单起点bfs差不多,唯一不同的就是在刚开始入队的时候将两个起点都入队。可以说是对两个不同根节点的树进行搜索吧(两棵树根节点可相同可不同,枝叶可交叉可不交叉),主要思路就是这个样子喽,剩下的细节就看个人怎么处理了。同样也可以类比到多起点的搜索。而且如果单纯的暴力枚举的话会计算大量的重复所以可以增加一个dat数组讲草的位置保存下来,进行一些优化。(本人对图的建坐标方式可能恰好相反,见谅!)。

这是我的代码运行结果(前一次写的TLE了(小声图片说明

#include <bits/stdc++.h>
using namespace std;
int x,y;
const int MAX = 15;
int dir[][2] = {{-1,0},{0,-1},{1,0},{0,1}};
char vis[MAX][MAX],cur[MAX][MAX]; 
int path[MAX][MAX];     //这个二维数组记录对草对两个起点的最大距离(也就是火烧到此处的时间
struct node{
    int x,y;
    node(int xx=0,int yy=0):
        x(xx),y(yy){}
};
#define check(dx,dy) (0<=dx && dx<x && 0<=dy && dy<y)
vector dat;   //这个保存草的位置
int bfs(node fir,node sec)
{
    memset(path,0,sizeof path);
    memcpy(cur,vis,sizeof vis);
    queue que;
    que.push(fir),que.push(sec);   //两个结点同时入队
    cur[fir.y][fir.x] = '.';cur[sec.y][sec.x] = '.';
    while (!que.empty())
    {
        node tmp = que.front(); que.pop();
        for (int i=0;i<4;i++)
        {
            int dx = tmp.x+dir[i][0],dy = tmp.y+dir[i][1];
            if (check(dx,dy) && '#'==cur[dy][dx])
            {
                que.push(node(dx,dy));
                path[dy][dx] = path[tmp.y][tmp.x] + 1;
                cur[dy][dx] = '.';
            }
        }        
    }
    int res = -0x3f3f3f3f;
    for (int i=0;i<y;i++)
        for (int j=0;j<x;j++)
        {
            if (path[i][j]>res)
                res = path[i][j];
            if ('#'==cur[i][j])
                return -1;   //如果发现草没有烧完,就返回-1,否则返回时间
        }
    return res;
}
int main()
{
    int t;
    while (cin >> t){
        int count = 0;
        while (t--){
            cin >> y >> x;
            dat.clear();
            for (int i=0;i<y;i++)
            {
                scanf("%s",vis[i]);
                for (int j=0;j<x;j++)
                    if ('#'==vis[i][j])
                        dat.push_back(node(j,i));
            }
            int ans = 0x3f3f3f3f;  //枚举
            for (int i=0;i<dat.size();i++)
                for (int j=i;j<dat.size();j++)
                {
                    int tmp = bfs(dat[i],dat[j]);
                    if (-1==tmp)
                        continue;
                    if (tmp<ans)
                        ans = tmp;
                }
            if (0x3f3f3f3f==ans)
                ans = -1;
            cout << "Case " << ++count << ": " << ans << endl;
        }
    }
    return 0;
}
全部评论

相关推荐

牛客339922477号:都不用reverse,直接-1。一行。啥送分题
点赞 评论 收藏
分享
Yushuu:你的确很厉害,但是有一个小问题:谁问你了?我的意思是,谁在意?我告诉你,根本没人问你,在我们之中0人问了你,我把所有问你的人都请来 party 了,到场人数是0个人,誰问你了?WHO ASKED?谁问汝矣?誰があなたに聞きましたか?누가 물어봤어?我爬上了珠穆朗玛峰也没找到谁问你了,我刚刚潜入了世界上最大的射电望远镜也没开到那个问你的人的盒,在找到谁问你之前我连癌症的解药都发明了出来,我开了最大距离渲染也没找到谁问你了我活在这个被辐射蹂躏了多年的破碎世界的坟墓里目睹全球核战争把人类文明毁灭也没见到谁问你了😆
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务