poj3206(bfs+最小生成树)

 

传送门:Borg Maze

题意:有一个迷宫,里面有一些外星人,外星人用字母A表示,#表示墙,不能走,空格可以走,从S点出发,在起点S和A处可以分叉走,问找到所有的外星人的最短路径是多少?

分析:分别bfs由S和所有A出发到其他点的距离,然后建好图进行最小生成树处理即可。

#include <cstdio>

#include <cstring>

#include <string>

#include <cmath>

#include <iostream>

#include <algorithm>

#include <queue>

#include <cstdlib>

#include <stack>

#include <vector>

#include <set>

#include <map>

#define LL long long

#define mod 100000000

#define inf 0x3f3f3f3f

#define eps 1e-6

#define N 110

#define FILL(a,b) (memset(a,b,sizeof(a)))

#define lson l,m,rt<<1

#define rson m+1,r,rt<<1|1

#define PII pair<int,int>

using namespace std;

struct edge

{

    int u,v,w;

    edge() {}

    edge(int u,int v,int w):u(u),v(v),w(w){}

    bool operator<(const edge &a)const

    {

        return w<a.w;

    }

} e[N*N];

struct node

{

    int x,y,step;

    node(){}

    node(int x,int y,int step):x(x),y(y),step(step){}

};

int fa[N],tot,total;

char str[N][N];

int num[N][N],vis[N][N],n,m;

int find(int x)

{

    return fa[x]==x?x:fa[x]=find(fa[x]);

}

int MST(int n)

{

    int ans=0;

    for(int i=1;i<=n;i++)fa[i]=i;

    sort(e,e+tot);

    for(int i=0; i<tot; i++)

    {

        int a=find(e[i].u);

        int b=find(e[i].v);

        if(a==b)continue;

        fa[a]=b;

        ans+=e[i].w;

    }

    return ans;

}

bool judge(int a,int b)

{

    return a>=1&&a<=n&&b>=1&&b<=m&&str[a][b]!='#'&&!vis[a][b];

}

void bfs(int x,int y)

{

    queue<node>que;

    while(!que.empty())que.pop();

    FILL(vis,0);

    vis[x][y]=1;

    que.push(node(x,y,0));

    while(!que.empty())

    {

        node now=que.front();que.pop();

        for(int i=-1;i<=1;i++)

        for(int j=-1;j<=1;j++)

        {

            if(i+j==0||i==j)continue;

            int a=now.x+i,b=now.y+j,step=now.step+1;

            if(judge(a,b))

            {

                if(str[a][b]=='A'||str[a][b]=='S')

                {

                    e[tot++]=edge(num[x][y],num[a][b],step);

                }

                vis[a][b]=1;

                que.push(node(a,b,step));

            }

        }

    }

}

int main()

{

    int T;

    scanf("%d",&T);

    while(T--)

    {

        scanf("%d%d",&m,&n);

        gets(str[0]);

        for(int i=1;i<=n;i++)

            gets(str[i]);

        total=0;tot=0;

        for(int i=1;i<=n;i++)

        for(int j=1;j<=m;j++)

        {

            if(str[i][j]=='A'||str[i][j]=='S')

            {

                num[i][j]=++total;

            }

        }

        for(int i=1;i<=n;i++)

        for(int j=1;j<=m;j++)

        {

            if(str[i][j]=='A'||str[i][j]=='S')

            {

                bfs(i,j);

            }

        }

        printf("%d\n",MST(total));

    }

}
View Code

 

你可能感兴趣的:(最小生成树)