血色先锋队【BFS】

题目大意:

巫妖王的天灾军团终于卷土重来,血色十字军组织了一支先锋军前往诺森德大陆对抗天灾军团,以及一切沾有亡灵气息的生物。孤立于联盟和部落的血色先锋军很快就遭到了天灾军团的重重包围,现在他们将主力只好聚集了起来,以抵抗天灾军团的围剿。可怕的是,他们之中有人感染上了亡灵瘟疫,如果不设法阻止瘟疫的扩散,很快就会遭到灭顶之灾。大领主阿比迪斯已经开始调查瘟疫的源头。原来是血色先锋军的内部出现了叛徒,这个叛徒已经投靠了天灾军团,想要将整个血色先锋军全部转化为天灾军团!无需惊讶,你就是那个叛徒。在你的行踪败露之前,要尽快完成巫妖王交给你的任务。

军团是一个N行M列的矩阵,每个单元是一个血色先锋军的成员。感染瘟疫的人,每过一个小时,就会向四周扩散瘟疫,直到所有人全部感染上瘟疫。你已经掌握了感染源的位置,任务是算出血色先锋军的领主们感染瘟疫的时间,并且将它报告给巫妖王,以便对血色先锋军进行一轮有针对性的围剿。


思路:

裸的BFS,读入每个起始点的位置后就可以求出图中每一个点的最短马哈顿距离,求完之后再读入终点,O(1)输出即可。 
时间复杂度:O(nm)


代码:

#include <cstdio>
#include <iostream>
using namespace std;

const int dx[]={0,0,0,-1,1};
const int dy[]={0,1,-1,0,0};
int n,m,k,t,x,y,a[1011][1011],state[10000011][5],head,tail,dis[1011][1011];

void bfs() 
{
    do
    {
        head++;
        for (int i=1;i<=4;i++)
        {
            int xx=state[head][1]+dx[i];
            int yy=state[head][2]+dy[i];
            if (a[xx][yy]||xx<1||xx>n||yy<1||yy>m) continue;  //出界或已经到达
            tail++;
            a[xx][yy]=1;
            state[tail][1]=xx;
            state[tail][2]=yy;
            dis[xx][yy]=dis[state[head][1]][state[head][2]]+1;  //记录最短距离
        }
    }
    while (head<tail);
}

int main()
{
    scanf("%d%d%d%d",&n,&m,&k,&t);
    for (int i=1;i<=k;i++)
    {
        scanf("%d%d",&x,&y);
        tail++;
        state[tail][1]=x;
        state[tail][2]=y;
        a[x][y]=1;
    }
    bfs();
    for (int i=1;i<=t;i++)
    {
        scanf("%d%d",&x,&y);
        printf("%d\n",dis[x][y]);
    }
    return 0;
}

 

posted @ 2018-07-31 21:56  全OI最菜  阅读(480)  评论(0编辑  收藏  举报