codevs 第一道题

先贴描述

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

数据范围及提示 Data Size & Hint

见描述

  这题恶心的要死;

  做完整个人都是蒙比的;

  刚开始连思路都没有,还是看了题解才知道用搜索加最小生成树来做;

  然后我开始敲代码;

  第一遍敲完编译不通过,改了很久编译才通过;

  然后贴数据输出;

  结果连城市的数量都错;

  然后我就努力的调啊调;

  最后我发现,字符第一个元素是0,我tm却从1开始循环(这告我们脑子是个好东西);

  然后继续贴数据;

  第二个样例又不过了;

  好,继续改;

  然后,4向搜索问题一大堆。。(这告诉我们认真敲代码很重要);

  然后样例都过了;

  然后提交: 全wa,0分(我勒个擦!!);

  全wa后我开始思考为什么全wa;

  我发现可能是输入的问题;

  然后改输入,a了一个点;

  可能不是输入的问题;

  然后,我又把题目读了一边;

  如果某两个单元格有一个点相联系,则它们属于同一座建筑物。

  我日;

  我是按4向连接的;

  好吧改一下;

  改成八项;

  然后;

  ac了!;

  好吧,说一下思路:

  先把所有的数据读入;

  建立一个imap数组用来把读入的数据弄成数字;

  ‘.’是0;

  ‘#’是-1;

  然后循环全部,找到-1就开始广搜,把相连的-1变成不同楼房的标记;

  然后循环每一个标记,上下左右四个方向搜索;

  注意:

  因为是桥在边上,所以 要同时搜索相邻的两个格;

  然后,把搜到的边都记下来,跑一遍最小生成树就ac了;

  附代码:

  

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std; int n,m,imap[][],ncon=;
char cmap[][];
const int dx[]={,-,-,,,,,,-};
const int dy[]={,,,,,,-,-,-};
struct node {
int name1,name2,dis;
};
struct node edge[];
int fa[],num=,ans=; int find(int x)
{
if(fa[x]==x) return x;
fa[x]=find(fa[x]);
return fa[x];
} void big(int x,int y,int dis)
{
imap[x][y]=dis;
for(int i=;i<=;i++)
{
if(x+dx[i]>&&x+dx[i]<=n&&y+dy[i]>&&y+dy[i]<=m)
{
if(imap[x+dx[i]][y+dy[i]]==-)
{
big(x+dx[i],y+dy[i],dis);
}
}
}
} void edge_add(int from,int to,int dis)
{
num++;
edge[num].name1=from;
edge[num].name2=to;
edge[num].dis=dis;
} void edge_find_up(int x,int y,int from,int dis)
{
if(y->&&x->) if(imap[x-][y-]!=&&imap[x-][y-]!=from) edge_add(from,imap[x-][y-],dis);
if(y+<=m&&x->) if(imap[x-][y+]!=&&imap[x-][y+]!=from) edge_add(from,imap[x-][y+],dis);
if(x->)
{
if(imap[x-][y]!=&&imap[x-][y]!=from) edge_add(from,imap[x-][y],dis);
else if(imap[x-][y]!=from) edge_find_up(x-,y,from,dis+);
}
} void edge_find_down(int x,int y,int from,int dis)
{
if(y->&&x+<=n) if(imap[x+][y-]!=&&imap[x+][y-]!=from) edge_add(from,imap[x+][y-],dis);
if(y+<=m&&x+<=n) if(imap[x+][y+]!=&&imap[x+][y+]!=from) edge_add(from,imap[x+][y+],dis);
if(x+<=n)
{
if(imap[x+][y]!=&&imap[x+][y]!=from)
{
// printf("%d %d\n",x+1,y);
edge_add(from,imap[x+][y],dis);
}
else if(imap[x+][y]!=from) edge_find_down(x+,y,from,dis+);
}
} void edge_find_lift(int x,int y,int from,int dis)
{
if(x->&&y->) if(imap[x-][y-]!=&&imap[x-][y-]!=from) edge_add(from,imap[x-][y-],dis);
if(x+<=n&&y->) if(imap[x+][y-]!=&&imap[x+][y-]!=from) edge_add(from,imap[x+][y-],dis);
if(y->)
{
if(imap[x][y-]!=&&imap[x][y-]!=from) edge_add(from,imap[x][y-],dis);
else if(imap[x][y-]!=from) edge_find_lift(x,y-,from,dis+);
}
} void edge_find_right(int x,int y,int from,int dis)
{
if(x->&&y+<=m) if(imap[x-][y+]!=&&imap[x-][y+]!=from) edge_add(from,imap[x-][y+],dis);
if(x+<=n&&y+<=m) if(imap[x+][y+]!=&&imap[x+][y+]!=from) edge_add(from,imap[x+][y+],dis);
if(y+<=m)
{
if(imap[x][y+]!=&&imap[x][y+]!=from)
{
// printf("%d %d\n",x,y+1);
edge_add(from,imap[x][y+],dis);
}
else if(imap[x][y+]!=from) edge_find_right(x,y+,from,dis+);
}
} void edge_build(int from,int x,int y)
{
if(x->) edge_find_up(x-,y,from,);
if(x+<=n) edge_find_down(x+,y,from,);
if(y->) edge_find_lift(x,y-,from,);
if(y+<=m) edge_find_right(x,y+,from,);
} int cmp(struct node a,struct node b)
{
return a.dis<b.dis;
} int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
cin>>cmap[i]+;
for(int j=;j<=m;j++)
{
if(cmap[i][j]=='#') imap[i][j]=-;
}
}
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
if(imap[i][j]==-)
{
ncon++;
big(i,j,ncon);
}
}
}
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
if(imap[i][j]!=) edge_build(imap[i][j],i,j);
}
}
sort(edge+,edge+num+,cmp);
int head=,zh=,xx,yy;
for(int i=;i<=ncon;i++) fa[i]=i;
while(head<=ncon&&zh<=num)
{
zh++;
xx=find(edge[zh].name1),yy=find(edge[zh].name2);
if(xx!=yy)
{
ans+=edge[zh].dis;
fa[xx]=yy;
head++;
}
}
/*for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++) printf(" %d",imap[i][j]);
printf("\n");
}*/
printf("%d\n%d %d\n",ncon,head,ans);
return ;
}

codevs 1002 搭桥的更多相关文章

  1. codevs 1002 搭桥x

    题目描述 Description 有一矩形区域的城市中建筑了若干建筑物,如果某两个单元格有一个点相联系,则它们属于同一座建筑物.现在想在这些建筑物之间搭建一些桥梁,其中桥梁只能沿着矩形的方格的边沿搭建 ...

  2. 搭桥(codevs 1002)

    题目描述 Description 有一矩形区域的城市中建筑了若干建筑物,如果某两个单元格有一个点相联系,则它们属于同一座建筑物.现在想在这些建筑物之间搭建一些桥梁,其中桥梁只能沿着矩形的方格的边沿搭建 ...

  3. 【wikioi】1002 搭桥(dfs+最小生成树)

    http://wikioi.com/problem/1002/ 今天开始又开始刷水了哈T_T.照着hzwer神犇的刷题记录刷!!! 题解: 一开始我也不会,但是我想到了直接爆搜T_T. 好吧,题解. ...

  4. Code VS 1002 搭桥

    题目描述 Description 有一矩形区域的城市中建筑了若干建筑物,如果某两个单元格有一个点相联系,则它们属于同一座建筑物.现在想在这些建筑物之间搭建一些桥梁,其中桥梁只能沿着矩形的方格的边沿搭建 ...

  5. 1、Codevs 必做:2833、1002、1003、2627、2599

    2833 奇怪的梦境  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description Aiden陷入了一个奇怪的梦境:他被困 ...

  6. 搭桥|codevs1002|最小生成树|Prim|并查集|Elena

    1002 搭桥  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题目描述 Description 有一矩形区域的城市中建筑了若干建筑物,如果某两个单元格有一个点 ...

  7. T1002 搭桥 codevs

    http://codevs.cn/problem/1002/  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题目描述 Description 有一矩形区域的城 ...

  8. Codevs 1010 过河卒== 洛谷 1002

     时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 如图,A 点有一个过河卒,需要走到目标 B 点.卒行走规则:可以向下.或者向右.同 ...

  9. 【codevs】刷题记录→_→(推荐看!)

    注:本文是我原先在csdn内写的一篇博文,现转到这里,两篇博文尽量同时更新. //#include<iostream->shuati> //define 为什么刷  学长☞hzwer ...

随机推荐

  1. Kotlin语法(类和对象)

    二.类和对象: 1. 类定义: 类的声明包含类名,类头(指定类型参数,主构造函数等等),以及类主体,用大括号包裹.类头和类体是可选的:如果没有类体可以省略大括号. class Invoice{ } 2 ...

  2. [android]AndroidInject框架——我的第一个android小型框架

    作为一个移动应用开发者,随着需求的日益增多,Android项目的越来越臃肿,代码量越来越大, 现在冷静下来回头看看我们的代码,有多少代码跟业务逻辑没什么关系的 所以,本人自不量力,在github上建了 ...

  3. Android自定义控件1

    概述 Android已经为我们提供了大量的View供我们使用,但是可能有时候这些组件不能满足我们的需求,这时候就需要自定义控件了.自定义控件对于初学者总是感觉是一种复杂的技术.因为里面涉及到的知识点会 ...

  4. 【代码笔记】iOS-GTMBase64

    一,工程文件. 二,代码. - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading th ...

  5. JS获取浏览器名和版本信息

    Navigator 对象包含有关浏览器的信息. Navigator 对象属性和方法: <html> <head> <title>JS完整获取浏览器信息</ti ...

  6. IrfanView 4.36 中文版发布了

    IrfanView 4.36 简体中文便携版 小而快的图片浏览器 仅仅不到2M的小软件,功能却能与体积大到几十M的ACDSee相媲美!这个软件就是IrfanView.图片.音频.视频浏览,图片批量格式 ...

  7. Token原理以及应用

    近期由于项目需要开发供第三方使用的api,在整个架构设计的一个环节中,对api访问需要进行认证,在这里我选择了token认证. 一:token的优势(此部分引自http://www.sumahe.cn ...

  8. C#实现函数默认值和C#4.0实现默认值

    static void Main(string[] args) { SayHello(); SayHello("侯志强"); Console.ReadKey(); } C#.0实现 ...

  9. PHP 5.3.0以上推荐使用mysqlnd驱动

    1. 什么是 mysqlnd 驱动 ? PHP 手册上的描述 : MySQL Native Driver is a replacement for the MySQL Client Library ( ...

  10. windows 远程桌面研究

    最近因为一个监控相关的项目,深入研究了一下 windows 的 远程桌面的相关知识. 1. 如何让关闭了远程桌面连接的用户,对应的 session 立即退出 windows server. 大家使用 ...