POJ 3026

来源:互联网 发布:centos 查看软件版本 编辑:程序博客网 时间:2024/04/30 11:36

题意:求S和A的最小生成树、

思路:对每个S和A跑一次BF 确定相连的距离、

#include<cmath>#include<cstring>#include<stdio.h>#include<algorithm>#include<queue>using namespace std;const int qq=205;char map[qq][qq];int path[qq][qq];int vis[qq][qq];int pre[qq];char tmp[qq];int tot,n,m;int dx[4]={1,-1,0,0};int dy[4]={0,0,1,-1};struct Edge{int u,v,w;bool operator < (const Edge &a)const{return w<a.w;}}edge[10000];struct Node{int x,y,len;};void Bfs(int x,int y){memset(vis,0,sizeof(vis)); Node tmp,ans;tmp.x=x;tmp.y=y;tmp.len=0;queue<Node>Q;//结构体没定义优先级不要使用priority_queue vis[x][y]=1;Q.push(tmp);while(!Q.empty()){tmp=Q.front();Q.pop();int a=tmp.x,b=tmp.y;//printf("%d %d\n",a,b);if(path[a][b]!=0&&(a!=x||b!=y)){edge[tot].u=path[x][y];edge[tot].v=path[a][b];edge[tot].w=tmp.len;++tot;}for(int i=0; i<4; ++i){int xx=a+dx[i];int yy=b+dy[i]; if(xx>=0&&xx<n&&yy>=0&&yy<m)if(map[xx][yy]!='#'&&!vis[xx][yy]){vis[xx][yy]=1;ans.len=tmp.len+1;ans.x=xx;ans.y=yy;Q.push(ans);}}}}int find(int x){return pre[x]==x?x:pre[x]=find(pre[x]);}int main(){int t;scanf("%d",&t);while(t--){scanf("%d%d",&m,&n);gets(tmp);memset(path, 0, sizeof(path));getchar();int ans=1;tot=0;for(int i=0; i<n; ++i) gets(map[i]);for(int i=0; i<n; ++i)for(int j=0; j<m; ++j)if(map[i][j]=='A'||map[i][j]=='S')path[i][j]=ans++;for(int i=0; i<n; ++i)for(int j=0; j<m; ++j)if(map[i][j]=='A'||map[i][j]=='S')Bfs(i,j);sort(edge, edge+tot);for(int i=0; i<=ans; ++i)pre[i]=i;int minx=0;for(int i=0; i<tot; ++i){//printf("%d %d %d\n",edge[i].u,edge[i].v,edge[i].w);int x=find(edge[i].u);int y=find(edge[i].v);if(x==y)continue;pre[y]=x;minx+=edge[i].w;}printf("%d\n",minx);}return 0;}


0 0