poj 3026 Borg Maze (bfs+prim)

来源:互联网 发布:生成二维码的软件 编辑:程序博客网 时间:2024/06/05 11:14

题意:在迷宫中找存在的外星人A撒。。开始是一个组织找,后来这个组织可以分裂成

            很多组。求找到所有外星人的最小步数。(分裂后,步数计算为所有组织的步数和)


思路:因为要保证每个外星人A都找到,加上组织所在起始点S,求最小步数。即求图中

           n个点的最小生成树(n=外星人的个数+1)。

            bfs找每两点间的距离。


1、这题要注意时间复杂度。

开始预处理时把所有外星人和组织起点横纵坐标记录后。用了两个for循环,来找每两点的

距离。这样要调用n*n次bfs去搜状态,结果tle。其实每次重复搜没必要。


将n*n复杂度可以降到n。也就是遍历n个点,以其中每个点作起点一次,来搜到达其他各点

的最短距离。


2、这题要注意数组大小

外星人最多100,加上组织起点S一共101个点。

数组开小就wa了。


3、这题读入迷宫行列后不能用getchar,因为后面不止是单纯的回车。还有多余空格。

要用gets()吃掉所有。


代码:

#include<cstdio>#include<iostream>#include<cstring>#include<cmath>#include<cstdlib>#include<queue>#define INF 0x3f3f3f3fusing namespace std;struct node{    int x,y;    int step;};char m[55][55];int r[110],c[110],ans,rear,x,y;int edge[110][110],dis[110];bool vis[110];bool v[55][55];int dx[]={-1,1,0,0};int dy[]={0,0,-1,1};queue<node> Q;void dist(int i){    while(!Q.empty())        Q.pop();    node a,b,tmp;    int num=0;    a.x=r[i],a.y=c[i];    a.step=0;    Q.push(a);    v[r[i]][c[i]]=1;    while(!Q.empty())    {        tmp=Q.front();        Q.pop();        for(int k=0;k<rear;k++)        {            if(tmp.x==r[k] && tmp.y==c[k])            {                edge[k][i]=edge[i][k]=tmp.step;                num++;                break;            }        }        if(num==rear)            break;        for(int k=0;k<4;k++)        {            b.x=tmp.x+dx[k];            b.y=tmp.y+dy[k];            b.step = tmp.step+1;            if(b.x>=1 && b.x<=y && b.y>=1&&b.y<=x && m[b.x][b.y]!='#'&& !v[b.x][b.y])            {                v[b.x][b.y]=1;                Q.push(b);            }        }    }}void prim(){    int u=0;    for(int i=1;i<rear;i++)    {        dis[i]=edge[u][i];    }    vis[u]=1;    for(int i=1;i<rear;i++)    {        int minc = INF;        for(int j=0;j<rear;j++)        {            if(!vis[j] && dis[j]<minc)            {                u=j;                minc=dis[j];            }        }        ans+=minc;        vis[u]=1;        for(int j=0;j<rear;j++)        {            if(!vis[j] && edge[u][j]<dis[j])                dis[j]=edge[u][j];        }    }}int main(){    int T,sx,sy;    char shit[50];    scanf("%d",&T);    while(T--)    {        memset(vis,0,sizeof(vis));        scanf("%d%d",&x,&y);        gets(shit);        for(int i=1;i<=y;i++)            gets(m[i]+1);        rear=0;        for(int i=1;i<=y;i++)        {            for(int j=1;j<=x;j++)            {                if(m[i][j]=='S')                {                    sx=i;                    sy=j;                }                else if(m[i][j]=='A')                {                    r[rear]=i;                    c[rear++]=j;                }            }        }        r[rear]=sx;        c[rear++]=sy;        for(int i=0;i<rear;i++)        {            memset(v,0,sizeof(v));            dist(i);        }        ans=0;        prim();        printf("%d\n",ans);    }    return 0;}



             

原创粉丝点击