题目链接: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_JUDGE freopen("test.in","r",stdin); freopen("test.out","w",stdout); #endif scanf("%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; }