【BFS+Prim】poj 3026 Borg Maze

32 篇文章 0 订阅
31 篇文章 0 订阅

http://poj.org/problem?id=3026

题意:从S开始找到一条到所有外星人A的通路,使得该通路总长度最短。

分析:暴搜找出所有A/S之间的边,然后用prim把所有最短的边连接起来。


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

const int NM=105;
/*k:外星人的个数,kk:外星人之间所有的边,c[][]:保存第i个外星人的位置*/
int k,kk,ans,n,m,c[55][55],vis[55][55],mark[NM];  
int a[4][2]={-1,0,1,0,0,-1,0,1};
char str[55][55];

struct Alien{
	int x,y,step;
}q[NM];
struct Node{
	int x,y,vau;
}qn[NM*NM];

void BFS()
{
	int i,j;
	kk=0;
	for(i=0;i<k;i++){
		queue<Alien>q1;
		Alien t,pt;
		
		memset(vis,0,sizeof(vis));
		ans=0;
		vis[q[i].x][q[i].y]=1;
		q1.push(q[i]);
		while(!q1.empty())
		{
			t=q1.front();q1.pop();
			if(ans==k-1) break;
			for(j=0;j<4;j++){
				pt.x=t.x+a[j][0];pt.y=t.y+a[j][1];
				if(!vis[pt.x][pt.y] && str[pt.x][pt.y]!='#' && 
					pt.x>=0 && pt.x<n && pt.y>=0 && pt.y<m)
				{
					vis[pt.x][pt.y]=1;
					pt.step=t.step+1;
					q1.push(pt);
					if(str[pt.x][pt.y]=='A' || str[pt.x][pt.y]=='S'){
						qn[kk].x=i;qn[kk].y=c[pt.x][pt.y];
						qn[kk++].vau=pt.step;
						ans++;
					}
				}
			}
		}
	}
}

bool comp(struct Node A,struct Node B){
	return A.vau<B.vau;
}

int prim()
{
	int i,res,t;
	for(i=0;i<k;i++) mark[i]=1;
	sort(qn,qn+kk,comp);
	mark[qn[0].x]=0;
	res=0;
	for(i=0;i<kk;i++){
		t=mark[qn[i].x]+mark[qn[i].y];
		if(t==1){
			res+=qn[i].vau;
			mark[qn[i].x]=mark[qn[i].y]=0;
			i=0;
		}
	}
	return res;
}

int main()
{
	int i,j,len,T;
	char s[NM];
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d",&m,&n);
		k=0;
		gets(s);  //只能用这货读取空格
		for(i=0;i<n;i++){
			gets(str[i]);
			len=strlen(str[i]);
			for(j=0;j<len;j++)
				if(str[i][j]=='A' || str[i][j]=='S'){
					c[i][j]=k;
					q[k].x=i;q[k].y=j;q[k++].step=0;
				}	
		}
		BFS();
		printf("%d\n",prim());
	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值