POJ 3026 (BFS+Prim)

来源:互联网 发布:excel2003修复软件 编辑:程序博客网 时间:2024/06/06 00:34

题目链接:http://poj.org/problem?id=3026

题意:

给出一个迷宫,连接迷宫中所有字母,每一格代价为1,求最小代价。

思路:

这题wa了9发= =!

题目很坑,要不是看了Discuss估计这个寒假都过不去这题。

先说一下思路,BFS预处理每一个字母到其他所有字母的距离,用数组记录下来,然后用Prim求出连接所有字母所需要的代价,即最小生成树。

这题难点在于一开始对数据的处理,现将所有字母编号,我用的是数组的方式,然后在BFS中预处理直接用编号数组会比较方便一点,Prim里可以直接用编号求出ans,基本上就是一棵裸Prim。

然后说一下这题的坑点:

在输入n,m之后会有一堆空格,getchar()只能接受一个,需要用gets()

另外一点,INF采用0x3f3f3f3f,0x3f还是太小了。

具体实现代码如下:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<queue>using namespace std;const int maxn=505;int T,n,m;char map[maxn][maxn];int dx[]={-1,1,0,0};int dy[]={0,0,-1,1};int num[maxn][maxn];int dis[maxn][maxn];int vis[maxn][maxn];struct node{int x,y;int step;};bool judge_State(int x,int y){if(x<0||x>=n||y<0||y>=m) return false;if(map[x][y]=='#') return false;if(vis[x][y]) return false;return true;}void BFS(int posx,int posy){memset(vis,0,sizeof(vis));queue<node>q;node s,e;s.x=posx,s.y=posy,s.step=0;vis[s.x][s.y]=1;q.push(s);while(!q.empty()){s=q.front();q.pop();if(num[s.x][s.y]!=-1){dis[num[posx][posy]][num[s.x][s.y]]=s.step;}for(int i=0;i<4;i++){e.x=s.x+dx[i];e.y=s.y+dy[i];e.step=s.step+1;if(judge_State(e.x,e.y)){vis[e.x][e.y]=1;q.push(e);}}}}const int INF=0x3f3f3f3f;int vist[maxn];int low[maxn];int cnt;int Prim(){int ans=0,pos=0;memset(vist,0,sizeof(vist));for(int i=0;i<cnt;i++){if(i!=pos){low[i]=dis[pos][i];}}vist[pos]=1;for(int i=0;i<cnt-1;i++){int x,min=INF;for(int j=0;j<cnt;j++){if(!vist[j]&&low[j]<min){min=low[x=j];}}if(min==INF)return -1;ans+=min;vist[x]=1;for(int j=0;j<cnt;j++){if(!vist[j]&&low[j]>dis[x][j]){low[j]=dis[x][j];}}}return ans;}int main(){#ifndef ONLINE_JUDGEfreopen("test.in","r",stdin);freopen("test.out","w",stdout);#endifscanf("%d",&T);while(T--){scanf("%d%d",&m,&n);gets(map[0]);memset(num,-1,sizeof(num));cnt=0;for(int i=0;i<n;i++){gets(map[i]);for(int j=0;j<m;j++){if(map[i][j]=='A'||map[i][j]=='S')num[i][j]=cnt++;}}for(int i=0;i<n;i++) {for(int j=0;j<m;j++) {if(num[i][j]!=-1)BFS(i,j);}}int ans=Prim();printf("%d\n",ans);}return 0;}



0 0