poj 3026(prim+BFS)

解题思路:

把输入原图中的‘A’和‘S’取出记录其坐标,然后在原图中用BFS求每个‘A’或‘S’到其他点的距离,便可得到每个‘A’或‘S’到其他‘A’(‘S’)的距离,因此可为这些点(‘A’或‘S’)构造一个新的邻接矩阵。对新的图用prim算法求最小生成树即可!

注意这没节操的输入!


//poj 3026

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

const int SIZE=60;
const int INF=0x7fffffff;

typedef struct node
{
    int x;
    int y;
}node;

int n, m;
char str[SIZE][SIZE];
node as[2*SIZE];
int tot;
int map[2*SIZE][2*SIZE];

queue<node> Q;

int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
int vis[SIZE][SIZE];

bool check(node v)
{
    if(v.x<0 || v.x>=n || v.y<0 || v.y>=n || vis[v.x][v.y]>=0 || str[v.x][v.y]=='#')
        return false;
    return true;
}

void bfs()
{
    node u,v;

    memset(map,0,sizeof(map));
    for(int i=0;i<tot;i++)
    {
        for(int ii=0;ii<SIZE;ii++)
            for(int jj=0;jj<SIZE;jj++)
                vis[ii][jj]=-1;
        Q.push(as[i]);
        vis[as[i].x][as[i].y]=0;
        while(!Q.empty())
        {
            u=Q.front(); Q.pop();
            for(int j=0;j<4;j++)
            {
                v.x=u.x+dir[j][0]; v.y=u.y+dir[j][1];
                if(!check(v)) continue;
                Q.push(v);
                vis[v.x][v.y]=vis[u.x][u.y]+1;
            }
        }

        for(int j=0;j<tot;j++)
            map[i][j]=vis[as[j].x][as[j].y];
    }
}

void prim(int u0)
{
    int nearV[2*SIZE], lowcost[2*SIZE],sum=0;

    for(int i=0;i<tot;i++)
    {
        lowcost[i]=map[u0][i];
        nearV[i]=u0;
    }
    nearV[u0]=-1;

    for(int i=1;i<tot;i++)
    {
        int minV=INF, u=-1;
        for(int j=0;j<tot;j++)
        {
            if(nearV[j]!=-1 && lowcost[j]<minV)
            {
                minV=lowcost[j];
                u=j;
            }
        }
        nearV[u]=-1;
        sum+=minV;

        for(int j=0;j<tot;j++)
        {
            if(nearV[j]!=-1 && lowcost[j]>map[u][j])
            {
                lowcost[j]=map[u][j];
                nearV[j]=u;
            }
        }
    }
    cout<<sum<<endl;
}

int main()
{
    int T;
    char kg[100];

    cin>>T;
    while(T--)
    {

        cin>>n>>m;
        gets(kg);
        tot=0;
        for(int i=0;i<m;i++)
        {
            //cin.get(); cin.get(str[i],SIZE);
            gets(str[i]);
            for(int j=0;j<n;j++)
                if(str[i][j]=='A' || str[i][j]=='S')
                    {
                        as[tot].x=i;
                        as[tot++].y=j;
                    }
        }

        bfs();
        prim(0);
    }

    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值