poj-3026 -Borg Maze -bfs+prim(MST)

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


题目给出一个最外面被#包围的图,求S到达所有A点,所需要走过的步数。
注意S会分身,A最多有100个,那么S可以分成100分,其实可以把S也看成A,求 使得图中所


有的A联通在一起 的一个 最小生成树,先用bfs求出 他们之间的 边权值,然后跑一遍prim


就OK。。。数据较小。。就都用暴力算法了


有个trick就是 n,m后面可能有空格,需要getchar掉。



#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
double min(double a,double b)
{ 	return a>b?b:a;}
double max(double a,double b)
{ 	return a<b?b:a;}
int inf=2147483647;
double eps=0.000001;   
int mp[55][55];
int n,m;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
struct node
{
	int x,y;node(){}
	node(int a,int b){x=a;y=b;}
	node(int a,int b,int c){x=a;y=b;w=c;}
	int w;
};  
struct edge
{
	int x,y,v;
	edge(){}
	edge(int a,int b,int c)
	{x=a,y=b,v=c;}
};edge tm[105*105]; 
int cmp(edge a,edge b)
{
	return a.v<b.v;
}  
int who[55][55];					//给A编号
node que[1000005];					//储存A位置的数组1		
int vis[105][105];					//求边权bfs过程记录访问过的点
int cost[105][105];					// 记录边权
void bfs(int xx,int yy,int num)		//求边权
{
	memset(vis,0,sizeof(vis));
	queue<node> q;int i;
	q.push(node(xx,yy,0));
	int flag=0;
	vis[xx][yy]=1;
	while(!q.empty())
	{
		node tp=q.front();q.pop(); 
	 	for (i=0;i<4;i++)
		{
			int x=tp.x+dx[i];int y=tp.y+dy[i]; 
			if (vis[x][y]||mp[x][y]=='#') continue;
			if (who[x][y])	
			{
				cost[num][who[x][y]]=tp.w+1; 
				flag=tp.w+1;
			}
			q.push(node(x,y,tp.w+1));
			vis[x][y]=1;
		}
	} 

}
int dis[105];
int main()

{ 


	
	int  i,j,k;  
	int t;cin>>t;
	while(t--)
	{ 
		int ok=0;
		int que_ok=0; 
		cin>>m>>n;
		char c=getchar();
		while(c!='\n') c=getchar();
	memset(cost,0,sizeof(cost));
	memset(who,0,sizeof(who));
		for (i=1;i<=n;i++)
		{
			for (j=1;j<=m;j++)
			{
				scanf("%c",&mp[i][j]);
				if (mp[i][j]=='S')
				{mp[i][j]='A';} 
				
				if (mp[i][j]=='A')
				{que[++que_ok]=node(i,j);who[i][j]=que_ok;}
			}
			getchar();
		}
		 
		for (i=1;i<=que_ok;i++) 
			bfs(que[i].x,que[i].y,i);  

		dis[1]=0;
		int ans=0; 
		for (i=2;i<=que_ok;i++)
		{
			if (cost[1][i])
				dis[i]=cost[1][i];
			else
				dis[i]=inf;
		}
		
		for (i=1;i<que_ok;i++)
		{
			int minn=inf;
			int mini=0;
			for (j=1;j<=que_ok;j++)
			{
				 
				if (dis[j]<minn&&dis[j]!=0)
				{
					minn=dis[j];mini=j;
				}
			}
			dis[mini]=0;
			ans+=minn;
			for(j=1;j<=que_ok;j++)
			{
				if (dis[j]&&cost[mini][j])
					if (cost[mini][j]<dis[j])
						dis[j]=cost[mini][j];
			}
		}
		printf("%d\n",ans);
	}
	
	
	
	return 0;
}


你可能感兴趣的:(poj-3026 -Borg Maze -bfs+prim(MST))