http://poj.org/problem?id=3026
题目给出一个最外面被#包围的图,求S到达所有A点,所需要走过的步数。
注意S会分身,A最多有100个,那么S可以分成100分,其实可以把S也看成A,求 使得图中所
有的A联通在一起 的一个 最小生成树,先用bfs求出 他们之间的 边权值,然后跑一遍prim
就OK。。。数据较小。。就都用暴力算法了
有个trick就是 n,m后面可能有空格,需要getchar掉。
题目给出一个最外面被#包围的图,求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位置的数组1
int 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];
else
dis[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;
}