A minimal spanning tree on the Codevs. My method may be more troublesome ... DFS looking for buildings, and then Kruskal. The use of this and the check set is a key.
This is what the Devil code length.
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define Maxe 100005
#define MAXV 10005
using namespace Std;
struct Edge
{
int u,v,w;
}e[maxe];
struct Building
{
int A, B;
}REGIS[MAXV];
int n,m,map[55][55],vis[55][55],cnt=0,cntt=0,nume=0,father[5005];
int dx[]={0,0,1,1,1,0,-1,-1,-1},dy[]={0,-1,-1,0,1,1,1,0,-1};\
int num=0,sum=0;
Char s[55];
BOOL Judge (int x,int y)
{
if ((x>=1) && (x<=n) && (y>=1) && (y<=m) && (map[x][y]==1))
return true;
return false;
}
BOOL CMP (Edge X,edge y)
{
Return x.w<y.w;
}
void Dfs (int x,int y,int fath)
{
Vis[x][y]=1;regis[++cntt].a=x;regis[cntt].b=y;
father[(x-1) *m+y]=fath;
for (int i=1;i<=8;i++)
{
if ((Judge (x+dx[i],y+dy[i)) ==true) && (vis[x+dx[i]][y+dy[i]]==0))
DFS (X+dx[i],y+dy[i],fath);
}
}
void Addedge (int uu,int vv,int ww)
{
E[++nume].u=uu;
E[NUME].V=VV;
E[NUME].W=WW;
}
void Build ()
{
for (int i=1;i<=cntt;i++)
{
int kx=regis[i].a,ky=regis[i].b;
int Up=max (1,regis[i].a-1), Down=min (n,regis[i].a+1);
for (int j=up;j<=down;j++)
{
for (int k=1;k<=m;k++)
{
if (map[j][k]==1)
Addedge ((kx-1) *m+ky, (j-1) *m+k,abs (ky-k)-1);
}
}
int Left=max (1,regis[i].b-1), Right=min (m,regis[i].b+1);
for (int j=left;j<=right;j++)
{
for (int k=1;k<=n;k++)
{
if (map[k][j]==1)
Addedge ((kx-1) *m+ky, (k-1) *m+j,abs (kx-k)-1);
}
}
}
}
int getfather (int x)
{
if (X!=father[x])
Father[x]=getfather (Father[x]);
return father[x];
}
void Unionn (int x,int y)
{
X=getfather (x);
Y=getfather (y);
if (x!=y)
Father[x]=y;
}
BOOL Same (int x,int y)
{
if (Getfather (x) ==getfather (y))
return true;
return false;
}
void Kruskal ()
{
for (int i=1;i<=nume;i++)
{
if (Same (E[I].U,E[I].V) ==false)
{
Unionn (E[I].U,E[I].V);
num++;
SUM=SUM+E[I].W;
}
}
}
int main ()
{
memset (map,0,sizeof (map));
memset (vis,0,sizeof (VIS));
scanf ("%d%d", &n,&m);
for (int i=1;i<=n;i++)
{
scanf ("%s", s);
for (int j=0;j<m;j++)
if (s[j]== ' # ') map[i][j+1]=1;
}
for (int i=1;i<=n*m;i++)
Father[i]=i;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
{
if ((vis[i][j]==0) && (map[i][j]==1))
{
Vis[i][j]=1;
DFS (I,j, (i-1) *m+j);
cnt++;
}
}
printf ("%d\n", CNT);
Build ();
Sort (e+1,e+nume+1,cmp);
Kruskal ();
printf ("%d%d", num,sum);
return 0;
}
Codevs 1002 Bridging