您的位置:首页 > 其它

PKU3026最小生成树+BFS+prim

2010-05-18 21:07 399 查看
//题意:只有在点S或点A可以分,求从点S到达所有点A的最少步数。可以用BFS+Prim实现,BFS用来求得任意两点间

//
//可达所需的最少步数,从而能构成一张图,两点间的权值就是BFS求得的最少步数。然后用Prim求解。

#include<cstdio>
#include<memory>
#include<queue>
#define MAXX 0x7fffffff
using namespace std;

int d[4][2]={-1,0,1,0,0,-1,0,1};
int n,m,step[105][105],index[55][55],dist[105];
bool used[55][55],hash[105];
char s[55][55];

struct Point{
int x,y,step;
}edge[105];

void BFS(int k,int ans)
{
queue<Point> q;
Point cnt ,tp;
tp=edge[k],edge[k].step=0;
memset(used,true,sizeof(used));
used[tp.x][tp.y]=false;
q.push(tp);
while(!q.empty())
{
cnt=q.front();
q.pop();
for(int i=0;i<4;i++)
{
tp.x=cnt.x+d[i][0];
tp.y=cnt.y+d[i][1];
tp.step=1 +cnt.step;//错误代码tp.step=1 +tp.step;
if(tp.x>=0&&tp.x<m&&tp.y>=0&&tp.y<n&&used[tp.x][tp.y]&&s[tp.x][tp.y]!='#')
{
if(s[tp.x][tp.y]=='A')
step[k][index[tp.x][tp.y]]=step[index[tp.x][tp.y]][k]=tp.step;//这个里面的所有tp 换成cnt即为我的错误代码
used[tp.x][tp.y]=false;q.push(tp);//忘记tp 进站
}
}
}
}
int Prim(int ans)
{
int i,j,sum=0;
for( i=1;i<=ans;i++)
{
dist[i]=step[1][i];
hash[i]=false;
}
hash[1]=true;
for(i=1;i<=ans;i++)
{  int max=MAXX,u=1;//为什么要没次初始化u=1
for(j=1;j<=ans;j++)
if(dist[j]<max&&!hash[j])
max=dist[j],u=j;
sum+=dist[u];hash[u]=true;//错误代码sum+=max

for(int k=1;k<=ans;k++)
if(step[u][k]<dist[k]&&!hash[k])
dist[k]=step[u][k];
}
return sum;
}

int main()
{
int T,i,j;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
char buff[101];
int ans=1;
gets(buff);
for( i=0;i<m;i++)
{
for( j=0;j<n;j++)
{
scanf("%c",&s[i][j]);
if(s[i][j]=='S')
s[i][j]='A',edge[1].x=i,edge[1].y=j,index[i][j]=1;
else
if(s[i][j]=='A')
edge[++ans].x=i,edge[ans].y=j,index[i][j]=ans;
}
getchar();
}
for( i=1;i<=ans;i++)
{
for( j=1;j<=ans;j++)
step[i][j]=MAXX;
step[i][i]=0;
}
for( i=1;i<=ans;i++)
BFS(i,ans);
printf("%d/n",Prim(ans));
}
system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: