codevs 1002 搭桥

题目描述 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

分析:

dfs+krustal。

先搜索出每栋不同的楼,并且计算楼与楼之间的间隔。

再利用最小生成树算法将其可联通边联通即可。

#include<iostream>
#include<algorithm>
using namespace std;
char a[60][60];
int book[60][60];
int fx[3601];
int n,m;
int dx[9]={0,0,0,1,-1,1,1,-1,-1},dy[9]={0,1,-1,0,0,1,-1,1,-1};
int cnt=0,cnt_b=0;
struct node{
    int s,f,w;
}t[3601];
bool cmp(const node &a,const node &b)
{
    return a.w<b.w;
}
void dfs(int x,int y)
{
    book[x][y]=cnt;
    for(int i=1;i<=8;++i)
    {
        int tx=x+dx[i],ty=y+dy[i];
        if(a[tx][ty]==‘#‘)
        {
            a[tx][ty]=‘.‘;
            dfs(tx,ty);
        }
    }
}
void find(int x,int y)
{
    for(int i=1;i<=m;++i)
    {
        if(y+i>m)break;
        if(book[x][y+1]==book[x][y])break;
        for(int j=1;j<=8;++j)
        {
            int tx=x+dx[j],ty=y+i+dy[j];
            if(book[tx][ty]!=0&&book[tx][ty]!=book[x][y])
            {
                ++cnt_b;
                t[cnt_b].s=book[x][y];
                t[cnt_b].f=book[tx][ty];
                t[cnt_b].w=i;
            }
        }
    }
    for(int i=1;i<=n;++i)
    {
        if(x+i>n)break;
        if(book[x+1][y]==book[x][y])break;
        for(int j=1;j<=8;++j)
        {
            int tx=x+i+dx[j],ty=y+dy[j];
            if(book[tx][ty]!=0&&book[tx][ty]!=book[x][y])
            {
                ++cnt_b;
                t[cnt_b].s=book[x][y];
                t[cnt_b].f=book[tx][ty];
                t[cnt_b].w=i;
            }
        }
    }
}
int find(int n)
{
    if(fx[n]==n)return n;
    else return fx[n]=find(fx[n]);
}
bool merge(int s,int f)
{
    int a=find(s),b=find(f);
    if(a!=b)
    {
        fx[b]=a;
        return 1;
    }
    else return 0;
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n*m;++i)fx[i]=i;
    for(int i=1;i<=n;++i)
    for(int j=1;j<=m;++j)cin>>a[i][j];
    for(int i=1;i<=n;++i)
    {
        for(int j=1;j<=m;++j)
        {
            if(a[i][j]==‘#‘)
            {
                a[i][j]=‘.‘;
                ++cnt;
                dfs(i,j);
            }
        }
    }
/*    for(int i=1;i<=n;++i)
    {
        for(int j=1;j<=m;++j)
        {
            cout<<book[i][j]<<" ";
        }
        cout<<endl;
    }
*/
    for(int i=1;i<=n;++i)
    {
        for(int j=1;j<=m;++j)
        {
            if(book[i][j]!=0)find(i,j);
        }
    }
//    for(int i=1;i<=cnt_b;++i)cout<<t[i].s<<" "<<t[i].f<<" "<<t[i].w<<endl;
    sort(t+1,t+cnt_b+1,cmp);
    int k=0,sum=0;
    for(int i=1;i<=cnt_b;++i)
    {
        if(merge(t[i].s,t[i].f))
        {
            ++k;
            sum+=t[i].w;
        }
    }
    cout<<cnt<<endl;
    cout<<k<<" "<<sum;
    return 0;
}
时间: 2024-12-26 10:58:05

codevs 1002 搭桥的相关文章

1002 搭桥-最小生成树 图论

题目地址:http://codevs.cn/problem/1002/ 这道题考察最小生成树和图的相关知识, 用到了二维到一维的转换(n行m列 坐标转化:(i,j)->  i*m+j ) 进一步利用一维数组做并查集处理,在搭桥过程中 要根据距离来搭桥,搭桥后要进行合并(注意 n个建筑物,n-1座桥就行了). 题目描述 Description 有一矩形区域的城市中建筑了若干建筑物,如果某两个单元格有一个点相联系,则它们属于同一座建筑物.现在想在这些建筑物之间搭建一些桥梁,其中桥梁只能沿着矩形的方格

wikioi 1002 搭桥

题意:这题刚开始看错题意了,原来桥是建在一条直线上就行,不管距离多远. 思路:dfs求第一问答案,然后最小生成树搞,不能建桥的边就设为INF就行了,然后如果用到INF的边就加上0就行了.这样跑一遍最小生成树就是答案. #pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream> #include<cstdio> #include<cstring> #include

搭桥(最小生成树)

codevs——1002 搭桥 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 有一矩形区域的城市中建筑了若干建筑物,如果某两个单元格有一个点相联系,则它们属于同一座建筑物.现在想在这些建筑物之间搭建一些桥梁,其中桥梁只能沿着矩形的方格的边沿搭建,如下图城市1有5栋建筑物,可以搭建4座桥将建筑物联系起来.城市2有两座建筑物,但不能搭建桥梁将它们连接.城市3只有一座建筑物,城市4有3座建筑物,可以搭建一座桥梁联系两栋建筑物,

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

2833 奇怪的梦境 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description Aiden陷入了一个奇怪的梦境:他被困在一个小房子中,墙上有很多按钮,还有一个屏幕,上面显示了一些信息.屏幕上说,要将所有按钮都按下才能出去,而又给出了一些信息,说明了某个按钮只能在另一个按钮按下之后才能按下,而没有被提及的按钮则可以在任何时候按下.可是Aiden发现屏幕上所给信息似乎有矛盾,请你来帮忙判断. 输入描述 Input Description

codevs1002 搭桥

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

7、8月刷题总结

准备开学了囧,7.8月刷题记录,以后好来复习,并且还要好好总结! 数据结构: splay: [BZOJ]1503: [NOI2004]郁闷的出纳员(Splay) [BZOJ]1269: [AHOI2006]文本编辑器editor(Splay) [BZOJ]1507: [NOI2003]Editor(Splay) treap: [BZOJ]1862: [Zjoi2006]GameZ游戏排名系统 & 1056: [HAOI2008]排名系统(treap+非常小心) [BZOJ]3224: Tyvj

【wikioi 1002】搭桥 dfs+kruskal

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

codevs 1506 传话 题解

Codevs 1506传话 题解 1506 传话--这个题目的解法很多,你能想到几种? 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 白银 Silver 题解 题目描述 Description 一个朋友网络,如果a认识b,那么如果a第一次收到某个消息,那么会把这个消息传给b,以及所有a认识的人. 如果a认识b,b不一定认识a. 所有人从1到n编号,给出所有"认识"关系,问如果i发布一条新消息,那么会不会经过若干次传话后,这个消息传回给了i,1<=i<=n

[ CodeVS冲杯之路 ] P2492

不充钱,你怎么AC? 题目:http://codevs.cn/problem/2492/ 在此先orz小胖子,教我怎么路径压缩链表,那么这样就可以在任意节点跳进链表啦(手动@LCF) 对于查询操作,直接树状数组(以下简称BIT)维护,修改操作就一个个暴力开方搞,再用差值单点更新BIT 不过这样会TLE,要加一点优化对不对,正如开头所说的路径压缩链表 路径压缩链表其实就是个并查集,在普通的链表里,删去两个连续的节点后会是下面这种情况,如删去2,3 当访问 2 的时候,会跳到3,但 3 已经删除了,