poj3026Borg Maze_最小生成树(广搜+prim算法)

来源:互联网 发布:淘宝冲量促销什么意思? 编辑:程序博客网 时间:2024/06/06 02:28

题目链接!


题很简单,就是求最小生成树的,难点就在于将图转化成边(带权值),就是这一块不好转化。

我想到了用广搜去找每个顶点到其他顶点的距离,但是在代码实现上有些困难,参考了别人的代码后就恍然大悟了,

觉得在prim算法上会很简单,但是同样也遇到了问题,就是在dis[]初始值时候,不知道初始谁了。总认为要先将S(开始搜索的地方)加入第一个dis值中,这样的一个错误的想法就卡住了。

看来还是没有深刻的理解最小生成树含义,从任何一个顶点出发都能到达各个顶点的最小价值。所以S和A的意义是一样的。

还有在进入广搜的时候,我也没有理解透彻!(最后和这个代码从下午死磕到晚上,最后还是别人

给我调试出来的。。。。别人要求我加入他的链接)

在广搜之前就要把求得各个顶点到顶点的最小距离d[]进行初始化,因为每次搜索的是传入的顶点到其它各个顶点的最小距离。


#include<stdio.h>#include<queue>#include<string.h>#define max 1<<31-1using namespace std;char map[55][55];int num_map[55][55];int vis[55][55];int time[55][55];int d[55][55];int dis[110];int book[110];int dx[]={-1,0,1,0};int dy[]={0,1,0,-1};int n,m,num;struct node{int u;int v;node(int uu,int vv):u(uu),v(vv){}node(){}}no[110];void bfs(node nd){memset(time,0,sizeof(time));    memset(vis,0,sizeof(vis));  int i,j;      queue<node>Q;Q.push(nd);vis[nd.u][nd.v]=1;while(!Q.empty()){node n1=Q.front();Q.pop();for(i=0;i<4;i++){int x=n1.u+dx[i];int y=n1.v+dy[i];if(x>=0&&x<n&&y>=0&&y<m&&vis[x][y]!=1&&map[x][y]!='#'){time[x][y]=time[n1.u][n1.v]+1;vis[x][y]=1;Q.push(node(x,y));if(num_map[x][y]>0){d[num_map[nd.u][nd.v]][num_map[x][y]]=time[x][y];}}}}}int prim(){memset(book,0,sizeof(book));int i,j,count=0,sum=0;for(i=1;i<=num;i++)  dis[i]=max;  dis[1]=0;while(count<num){int min=max;for(i=1;i<=num;i++){if(!book[i]&&dis[i]<min){j=i;min=dis[i];}}book[j]=1;count++;sum+=dis[j];for(i=1;i<=num;i++){if(!book[i]&&dis[i]>d[j][i]){ dis[i]=d[j][i];}  }}return sum;}int main(){int T,i,j;scanf("%d",&T);while(T--){memset(num_map,0,sizeof(num_map));scanf("%d%d",&m,&n);char str[110];gets(str);for(i=0;i<n;i++)   gets(map[i]);num=0;for(i=0;i<n;i++)  for(j=0;j<m;j++)  {  if(map[i][j]=='S'||map[i][j]=='A')  {  num_map[i][j]=++num;  }  }for(i=1;i<=num;i++)  for(j=1;j<=num;j++)      d[i][j]=max;        for(i=0;i<n;i++)     for(j=0;j<m;j++)     if(num_map[i][j]>0)       bfs(node(i,j));                 printf("%d\n",prim());  }return 0;}


0 0
原创粉丝点击