# Code VS 1002 搭桥

3 5

#...#

..#..

#...#

3 5

##...

.....

....#

3 5

#.###

#.#.#

###.#

3 5

#.#..

.....

....#

5

4 4

2

0 0

1

0 0

3

1 1

-----------------------------------------------------------------------------------------------------------------（分割线）

￥%&%#@……%&&%￥%......

假设当前枚举的点是（x,y) , 则这六个方向为：  （x,i）,(x+1,i) (x-1,i) ,(y,i),(y+1,i),(y-1,i），每次扫描到和当前点的联通块编号不相等的点时就更新最小距离。

```#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 60
#define M 250900
using namespace std;

int G[N][N];                //图数组

int en,n,r,c;            //边数，联通块个数，题目所描述的，r,c。

struct edge{
int s,e,d;
}ed[M];

bool operator < (const edge &a, const edge &b){            //重载运算符
return a.d < b.d;
}

void add_edge(int s,int e,int d){                //建边
en++;
ed[en].s= s,ed[en].e =e ,ed[en].d = d;
}
int fa[M];

int getf(int now){                        //并查集
if(now == fa[now])return now;
else return fa[now] = getf(fa[now]);
}

void kruskal(){                        //kruskal算法
sort(ed+1,ed+en+1);
for(int a = 1; a <= n; a++)fa[a] = a;
int ans = 0,num = 0;
for(int a = 1; a <= en; a++){
int f1 = getf(ed[a].s);
int f2 = getf(ed[a].e);
if(f1 != f2){
fa[f1] = f2;
ans += ed[a].d;
num++;
}
}
printf("%d %d\n",num,ans);
}

int tx[] = {0,0,1,1,-1,-1,1,-1};
int ty[] = {1,-1,1,-1,1,-1,0,0};

void dfs(int x,int y){                //求联通块
G[x][y] = n;
for(int i = 0; i < 8; i++){
int xx = tx[i]+x;
int yy = ty[i]+y;
if(xx >= 1 && xx <= r && yy >= 1 && yy <= c && (G[xx][yy] == -1))
dfs(xx,yy);
}
}

int g[1009][1009];

int xx,yy;
xx = x+1,yy = y+1;;
while(xx >= 1 && xx <= r && yy >= 1 && yy <= c && (G[xx][yy] != G[x][y])){
if(G[xx][yy] != 0)g[G[x][y]][G[xx][yy]] = min(g[G[x][y]][G[xx][yy]],yy-y-1);
yy++;
}
yy = y-1;
while(xx >= 1 && xx <= r && yy >= 1 && yy <= c && (G[xx][yy] != G[x][y])){
if(G[xx][yy] != 0)g[G[x][y]][G[xx][yy]] = min(g[G[x][y]][G[xx][yy]],y-yy-1);
yy--;
}
xx = x,yy = y+1;
while(xx >= 1 && xx <= r && yy >= 1 && yy <= c && (G[xx][yy] != G[x][y])){
if(G[xx][yy] != 0)g[G[x][y]][G[xx][yy]] = min(g[G[x][y]][G[xx][yy]],yy-y-1);
yy++;
}
yy = y-1;
while(xx >= 1 && xx <= r && yy >= 1 && yy <= c && (G[xx][yy] != G[x][y])){
if(G[xx][yy] != 0)g[G[x][y]][G[xx][yy]] = min(g[G[x][y]][G[xx][yy]],y-yy-1);
yy--;
}
xx = x-1,yy = y+1;
while(xx >= 1 && xx <= r && yy >= 1 && yy <= c && (G[xx][yy] != G[x][y])){
if(G[xx][yy] != 0)g[G[x][y]][G[xx][yy]] = min(g[G[x][y]][G[xx][yy]],yy-y-1);
yy++;
}
yy = y-1;
while(xx >= 1 && xx <= r && yy >= 1 && yy <= c && (G[xx][yy] != G[x][y])){
if(G[xx][yy] != 0)g[G[x][y]][G[xx][yy]] = min(g[G[x][y]][G[xx][yy]],y-yy-1);
yy--;
}

yy = y,xx = x+1;
while(xx >= 1 && xx <= r && yy >= 1 && yy <= c && (G[xx][yy] != G[x][y])){
if(G[xx][yy] != 0)g[G[x][y]][G[xx][yy]] = min(g[G[x][y]][G[xx][yy]],xx-x-1);
xx++;
}
xx = x-1;
while(xx >= 1 && xx <= r && yy >= 1 && yy <= c && (G[xx][yy] != G[x][y])){
if(G[xx][yy] != 0)g[G[x][y]][G[xx][yy]] = min(g[G[x][y]][G[xx][yy]],x-xx-1);
xx--;
}
yy = y+1,xx = x+1;
while(xx >= 1 && xx <= r && yy >= 1 && yy <= c && (G[xx][yy] != G[x][y])){
if(G[xx][yy] != 0)g[G[x][y]][G[xx][yy]] = min(g[G[x][y]][G[xx][yy]],xx-x-1);
xx++;
}
xx = x-1;
while(xx >= 1 && xx <= r && yy >= 1 && yy <= c && (G[xx][yy] != G[x][y])){
if(G[xx][yy] != 0)g[G[x][y]][G[xx][yy]] = min(g[G[x][y]][G[xx][yy]],x-xx-1);
xx--;
}
yy = y-1;xx = x+1;
while(xx >= 1 && xx <= r && yy >= 1 && yy <= c && (G[xx][yy] != G[x][y])){
if(G[xx][yy] != 0)g[G[x][y]][G[xx][yy]] = min(g[G[x][y]][G[xx][yy]],xx-x-1);
xx++;
}
xx = x-1;
while(xx >= 1 && xx <= r && yy >= 1 && yy <= c && (G[xx][yy] != G[x][y])){
if(G[xx][yy] != 0)g[G[x][y]][G[xx][yy]] = min(g[G[x][y]][G[xx][yy]],x-xx-1);
xx--;
}
}

int main(){
scanf("%d%d",&r,&c);
for(int i = 1; i <= r; i++){
char s[55];
scanf("%s",s);
for(int j = 0; j < c; j++)
if(s[j] == ‘#‘)G[i][j+1] = -1;
else G[i][j+1] = 0;
}
for(int i = 1; i <= r; i++){
for(int j = 1; j <= c; j++){
if(G[i][j] == -1){
n++;
dfs(i,j);
}
}
}

memset(g,0x3f,sizeof(g));

printf("%d\n",n);
for(int i = 1; i <= r; i++)
for(int j = 1; j <= c; j++)

for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
kruskal();
return 0;
}```

Code VS 1002 搭桥

(0)
(0)

0条