poj-3026 -Borg Maze -bfs+prim(MST)

来源:互联网 发布:卡廷森林 知乎 编辑:程序博客网 时间:2024/06/10 06:48
http://poj.org/problem?id=3026 


题目给出一个最外面被#包围的图,求S到达所有A点,所需要走过的步数。
注意S会分身,A最多有100个,那么S可以分成100分,其实可以把S也看成A,求 使得图中所


有的A联通在一起 的一个 最小生成树,先用bfs求出 他们之间的 边权值,然后跑一遍prim


就OK。。。数据较小。。就都用暴力算法了


有个trick就是 n,m后面可能有空格,需要getchar掉。



#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <algorithm>#include <queue>#include <map>#include <set>#include <vector>#include <iostream>using namespace std;double min(double a,double b){ return a>b?b:a;}double max(double a,double b){ return a<b?b:a;}int inf=2147483647;double eps=0.000001;   int mp[55][55];int n,m;int dx[4]={0,0,1,-1};int dy[4]={1,-1,0,0};struct node{int x,y;node(){}node(int a,int b){x=a;y=b;}node(int a,int b,int c){x=a;y=b;w=c;}int w;};  struct edge{int x,y,v;edge(){}edge(int a,int b,int c){x=a,y=b,v=c;}};edge tm[105*105]; int cmp(edge a,edge b){return a.v<b.v;}  int who[55][55];//给A编号node que[1000005];//储存A位置的数组1int vis[105][105];//求边权bfs过程记录访问过的点int cost[105][105];// 记录边权void bfs(int xx,int yy,int num)//求边权{memset(vis,0,sizeof(vis));queue<node> q;int i;q.push(node(xx,yy,0));int flag=0;vis[xx][yy]=1;while(!q.empty()){node tp=q.front();q.pop();  for (i=0;i<4;i++){int x=tp.x+dx[i];int y=tp.y+dy[i]; if (vis[x][y]||mp[x][y]=='#') continue;if (who[x][y]){cost[num][who[x][y]]=tp.w+1; flag=tp.w+1;}q.push(node(x,y,tp.w+1));vis[x][y]=1;}} }int dis[105];int main(){ int  i,j,k;  int t;cin>>t;while(t--){ int ok=0;int que_ok=0; cin>>m>>n;char c=getchar();while(c!='\n') c=getchar();memset(cost,0,sizeof(cost));memset(who,0,sizeof(who));for (i=1;i<=n;i++){for (j=1;j<=m;j++){scanf("%c",&mp[i][j]);if (mp[i][j]=='S'){mp[i][j]='A';} if (mp[i][j]=='A'){que[++que_ok]=node(i,j);who[i][j]=que_ok;}}getchar();} for (i=1;i<=que_ok;i++) bfs(que[i].x,que[i].y,i);  dis[1]=0;int ans=0; for (i=2;i<=que_ok;i++){if (cost[1][i])dis[i]=cost[1][i];elsedis[i]=inf;}for (i=1;i<que_ok;i++){int minn=inf;int mini=0;for (j=1;j<=que_ok;j++){ if (dis[j]<minn&&dis[j]!=0){minn=dis[j];mini=j;}}dis[mini]=0;ans+=minn;for(j=1;j<=que_ok;j++){if (dis[j]&&cost[mini][j])if (cost[mini][j]<dis[j])dis[j]=cost[mini][j];}}printf("%d\n",ans);}return 0;}


0 0
原创粉丝点击