Description
Input
Output
Sample Input
2 6 5 ##### #A#A## # # A# #S ## ##### 7 7 ##### #AAA### # A# # S ### # # #AAA### #####
Sample Output
8 11
Source
#include<stdio.h>prim:
#include<string.h>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<iterator>
using namespace std;
const int maxn=112;
bool vis2[maxn][maxn];
int dir[4][2]={1,0,-1,0,0,1,0,-1};
int x,y,n;
int num[maxn][maxn];
struct node
{
int from,to;
int weight;
}edge[maxn*maxn];
struct node2
{
int x,y;
int step;
}temp1,temp2;
int father[maxn];
char mat[maxn][maxn];
void unit(int n)
{
for(int i=0;i<=n;i++)
father[i]=i;
}
int find(int x)
{
if(x!=father[x])
father[x]=find(father[x]);
return father[x];
}
void merge(int aa,int bb)
{
if(aa!=bb)
father[aa]=bb;
}
int cmp(node a,node b)
{
return a.weight < b.weight;
}
int kruskal(int v_all)
{
sort(edge,edge+n,cmp);
unit(v_all);
int sum=0,m=0;
for(int i=0;i<n;i++)
{
int a=find(edge[i].from);
int b=find(edge[i].to);
if(a!=b)
{
merge(a,b);
sum+=edge[i].weight;
m++;
if(m==v_all-1)
break;
}
}
return sum;
}
bool is_legal(int x0,int y0)
{
if(x0<0 || y0<0 || x0>=y || y0>=x || mat[x0][y0]=='#')
return false;
return true;
}
void solve(int x,int y)
{
bool vis[maxn][maxn];
memset(vis,0,sizeof(vis));
queue<node2>qu;
while(!qu.empty())
qu.pop();
temp1.x=x;
temp1.y=y;
vis[x][y]=1;
temp1.step=0;
qu.push(temp1);
while(!qu.empty())
{
temp1=qu.front();
qu.pop();
for(int i=0;i<4;i++)
{
temp2=temp1;
temp2.x+=dir[i][0];
temp2.y+=dir[i][1];
temp2.step++;
if(!is_legal(temp2.x,temp2.y) || vis[temp2.x][temp2.y])
continue;
if(mat[temp2.x][temp2.y]=='A' || mat[temp2.x][temp2.y]=='S')
{
edge[n].from=num[x][y];
edge[n].to=num[temp2.x][temp2.y];
edge[n++].weight=temp2.step;
vis2[num[x][y]][num[temp2.x][temp2.y]]=1;
}
vis[temp2.x][temp2.y]=1;
qu.push(temp2);
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
n=0;
memset(vis2,0,sizeof(vis2));
int cnt=0;
scanf("%d%d",&x,&y);
gets(mat[0]);
for(int i=0;i<y;i++)
gets(mat[i]);
for(int i=0;i<y;i++)
for(int j=0;j<x;j++)
if(mat[i][j]=='A' || mat[i][j]=='S')
num[i][j]=cnt++;
for(int i=0;i<y;i++)
for(int j=0;j<x;j++)
if(mat[i][j] == 'A' || mat[i][j] == 'S')
solve(i,j);
printf("%d\n",kruskal(cnt));
}
return 0;
}
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<set> #include<vector> #include<iterator> using namespace std; const int maxn=105; int dir[4][2]={1,0,-1,0,0,1,0,-1}; int x,y; int num[maxn][maxn]; int dis[maxn][maxn]; struct node2 { int x,y; int step; }temp1,temp2; char mat[maxn][maxn]; int father[maxn]; int lowcost[maxn]; int closeset[maxn]; bool used[maxn]; bool is_legal(int x0,int y0) { if(x0<0 || y0<0 || x0>=y || y0>=x || mat[x0][y0]=='#') return false; return true; } int prim(int v_all) { int i,j,k; for(i=1;i<v_all;i++) { used[i]=0; lowcost[i]=dis[0][i]; // father[i]=-1; closeset[i]=0; } used[0]=1; int min,sum=0; for(i=1;i<=v_all-1;i++) { min=0x3f3f3f3f; j=0; for(k=0;k<v_all;k++) if(!used[k] &&lowcost[k] < min) { min=lowcost[k];//k这个点没进去,然后找他依附的点到他的距离 j=k; } used[j]=1; if(min==0x3f3f3f3f) return -1; sum+=min; father[j]=closeset[j]; for(k=1;k<v_all;k++) { if(!used[k] && lowcost[k]>dis[j][k]) { lowcost[k]=dis[j][k]; closeset[k]=j; } } } return sum; } void solve(int x,int y) { bool vis[maxn][maxn]; memset(vis,0,sizeof(vis)); queue<node2>qu; while(!qu.empty()) qu.pop(); temp1.x=x; temp1.y=y; vis[x][y]=1; temp1.step=0; qu.push(temp1); while(!qu.empty()) { temp1=qu.front(); qu.pop(); for(int i=0;i<4;i++) { temp2=temp1; temp2.x+=dir[i][0]; temp2.y+=dir[i][1]; temp2.step++; if(!is_legal(temp2.x,temp2.y) || vis[temp2.x][temp2.y]) continue; if(mat[temp2.x][temp2.y]=='A' || mat[temp2.x][temp2.y]=='S') { int a=num[x][y]; int b=num[temp2.x][temp2.y]; dis[a][b]=temp2.step; } vis[temp2.x][temp2.y]=1; qu.push(temp2); } } } int main() { int t; scanf("%d",&t); while(t--) { int cnt=0; scanf("%d%d",&x,&y); gets(mat[0]); for(int i=0;i<y;i++) gets(mat[i]); for(int i=0;i<y;i++) for(int j=0;j<x;j++) if(mat[i][j]=='A' || mat[i][j]=='S') num[i][j]=cnt++; for(int i=0;i<y;i++) for(int j=0;j<x;j++) if(mat[i][j] == 'A' || mat[i][j] == 'S') solve(i,j); printf("%d\n",prim(cnt)); } return 0; }