搭桥1002

1002 搭桥

 

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 黄金 Gold
 
 
 
题目描述 Description

有一矩形区域的城市中建筑了若干建筑物,如果某两个单元格有一个点相联系,则它们属于同一座建筑物。现在想在这些建筑物之间搭建一些桥梁,其中桥梁只能沿着矩形的方格的边沿搭建,如下图城市1有5栋建筑物,可以搭建4座桥将建筑物联系起来。城市2有两座建筑物,但不能搭建桥梁将它们连接。城市3只有一座建筑物,城市4有3座建筑物,可以搭建一座桥梁联系两栋建筑物,但不能与第三座建筑物联系在一起。

输入描述 Input Description

在输入的数据中的第一行包含描述城市的两个整数r 和c, 分别代表从北到南、从东到西的城市大小(1 <= <= 50 and 1 <=  c <= 50). 接下来的r 行, 每一行由个(“#”)和(“.”)组成的字符. 每一个字符表示一个单元格。“#”表示建筑物,“.”表示空地。

 

输出描述 Output Description

在输出的数据中有两行,第一行表示建筑物的数目。第二行输出桥的数目和所有桥的总长度。

样例输入 Sample Input

样例1

3 5

#...#

..#..

#...#

 

样例2

3 5

##...

.....

....#

 

样例3

3 5

#.###

#.#.#

###.#

 

样例4:

3 5

#.#..

.....

....#

 

样例输出 Sample Output

样例1

5

4 4

 

样例2

2

0 0

 

样例3

1

0 0

 

样例4

3

1 1

 
 
图论题
最小生成树。。。
两座城市之间搭桥,也就是连边。bfs 左,左上,左下,右,右上,右下,上,上左,上右,下,下左,下右。
联通联通块即可。
 
 
***************************************************************************************************************************

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
using namespace std;
const int maxn=0x7ff;
int pa[1000][1000];
bool f[1000][1000];
int xx[9]={0,0,0,1,-1,1,1,-1,-1};
int yy[9]={0,1,-1,0,0,1,-1,1,-1};
struct ww{
int x;
int y;
};
struct fo{
int f;
int t;
int d;
}am[maxn];
int n,m;
queue<ww> q;
void bfs(int i,int j,int qw){
memset(f,0,sizeof(f));
ww s;
s.x=i;s.y=j;
pa[i][j]=qw;
q.push(s);
while(!q.empty())
{
ww u=q.front();
q.pop();
int x=u.x,y=u.y;
for(int i=1;i<=8;i++){
int d=x+xx[i];
int h=y+yy[i];
if(d>=1&&d<=n&&h>=1&&h<=m&&!f[d][h]&&pa[d][h]==-1){
pa[d][h]=qw;
f[d][h]=1;
ww tw;
tw.x=d,tw.y=h;
q.push(tw);
}
}
}
}
int wq[maxn];
bool cmp(fo a,fo b){
return a.d<b.d;
}
int find(int a){
if(wq[a]!=a) return wq[a]=find(wq[a]);
else return a;
}
int main()
{
scanf("%d%d",&n,&m);
char x;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>x;
if(x=='#'){
pa[i][j]=-1;
}
}
}
int qwq=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(pa[i][j]==-1&&!f[i][j]){
bfs(i,j,++qwq);
}
}
}
int t=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(pa[i][j]){
for(int k=j;k>=1;k--){//左
if(pa[i][k]&&pa[i][k]!=pa[i][j]){
am[++t].f=pa[i][j];
am[t].t=pa[i][k];
am[t].d=abs(k-j-1);
}
}
for(int k=j;k>=1;k--){//左上
if(pa[i+1][k]&&pa[i+1][k]!=pa[i][j]){
am[++t].f=pa[i][j];
am[t].t=pa[i+1][k];
am[t].d=abs(k-j-1);
}
}
for(int k=j;k>=1;k--){//左下
if(pa[i-1][k]&&pa[i-1][k]!=pa[i][j]){
am[++t].f=pa[i][j];
am[t].t=pa[i-1][k];
am[t].d=abs(k-j-1);
}
}
for(int k=j;k<=m;k++){//右
if(pa[i][k]&&pa[i][k]!=pa[i][j]){
am[++t].f=pa[i][j];
am[t].t=pa[i][k];
am[t].d=abs(k-j-1);
}
}
for(int k=j;k<=m;k++){//右上
if(pa[i+1][k]&&pa[i+1][k]!=pa[i][j]){
am[++t].f=pa[i][j];
am[t].t=pa[i+1][k];
am[t].d=abs(k-j-1);
}
}
for(int k=j;k<=m;k++){//右下
if(pa[i-1][k]&&pa[i-1][k]!=pa[i][j]){
am[++t].f=pa[i][j];
am[t].t=pa[i-1][k];
am[t].d=abs(k-j-1);
}
}
for(int k=i;k>=1;k--){//上
if(pa[k][j]&&pa[k][j]!=pa[i][j]){
am[++t].f=pa[i][j];
am[t].t=pa[k][j];
am[t].d=abs(k-i-1);
}
}
for(int k=i;k>=1;k--){//上左
if(pa[k][j-1]&&pa[k][j-1]!=pa[i][j]){
am[++t].f=pa[i][j];
am[t].t=pa[k][j-1];
am[t].d=abs(k-i-1);
}
}
for(int k=i;k>=1;k--){//上右
if(pa[k][j+1]&&pa[k][j+1]!=pa[i][j]){
am[++t].f=pa[i][j];
am[t].t=pa[k][j+1];
am[t].d=abs(k-i-1);
}
}

for(int k=i;k<=n;k++){//下
if(pa[k][j]&&pa[k][j]!=pa[i][j]){
am[++t].f=pa[i][j];
am[t].t=pa[k][j];
am[t].d=abs(k-i-1);
}
}
for(int k=i;k<=n;k++){//下左
if(pa[k][j-1]&&pa[k][j-1]!=pa[i][j]){
am[++t].f=pa[i][j];
am[t].t=pa[k][j-1];
am[t].d=abs(k-i-1);
}
}
for(int k=i;k<=n;k++){//下右
if(pa[k][j+1]&&pa[k][j+1]!=pa[i][j]){
am[++t].f=pa[i][j];
am[t].t=pa[k][j+1];
am[t].d=abs(k-i-1);
}
}



}
}
}
sort(am+1,am+1+t,cmp);
long long ans=0;
int count=0;
for(int i=1;i<=qwq;i++){
wq[i]=i;
}
for(int i=1;i<=t;i++){
int x=find(am[i].f),y=find(am[i].t);
if(x!=y){
wq[x]=y;
ans+=am[i].d;
count++;
}
}
cout<<qwq<<endl<<count<<" "<<ans<<endl;
return 0;
}

————————————————————————————————————————————————————w—————————————————————————
 
 
posted @ 2016-03-29 21:34  .Tw  阅读(190)  评论(0)    收藏  举报