zoukankan      html  css  js  c++  java
  • codevs1002 搭桥

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

    见描述

    /*
    MST,建图略麻烦
    */
    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    #define ll long long
    #define fo(i,l,r) for(int i = l;i <= r;i++)
    #define fd(i,l,r) for(int i = r;i >= l;i--)
    using namespace std;
    const int N = 25005;
    ll read(){
        ll x=0,f=1;
        char ch=getchar();
        while(!(ch>='0'&&ch<='9')){if(ch=='-')f=-1;ch=getchar();};
        while(ch>='0'&&ch<='9'){x=x*10+(ch-'0');ch=getchar();};
        return x*f;
    }
    struct edge{
        int u;
        int v;
        int w;
        friend bool operator < (edge a,edge b){
            return a.w < b.w;
        }
    }e[N*3];
    int n,m,fa[N];
    char mp[105][105];
    int cnt,ans1,ans2,ans3;
    bool judge(int y,int x){
        if(y < 1 || y > n || x < 1 || x > m || mp[y][x] != '#') return false;
        return true;
    }
    void input(){
        n =read();
        m =read();
        char tmp;
        fo(i,1,n){
            fo(j,1,m){
                tmp = getchar();
                while(tmp !='.' && tmp != '#') tmp = getchar();
                mp[i][j] = tmp;
                if(tmp == '#') ans1++;
            }
        }
    }
    inline int jdz(int x){
        if(x<0)x=-x;return x;
    }
    inline void ins(int y1,int x1,int y2,int x2){
        cnt++;
        e[cnt].u = (y1-1)*m + x1;
        e[cnt].v = (y2-1)*m + x2;
        e[cnt].w = jdz(y1-y2) + jdz(x1-x2);
        if(y1 != y2) e[cnt].w--;
        if(x1 != x2) e[cnt].w--;
        //cout<<y1<<" "<<x1<<" "<<y2<<" "<<x2<<" "<<e[cnt].w<<endl;
    }
    void build(){
        fo(i,1,n){
            fo(j,1,m){
                if(mp[i][j] != '#') continue;
                fo(k,j+1,m){
                    if(judge(i,k)) ins(i,j,i,k);
                    if(judge(i+1,k)) ins(i,j,i+1,k);
                    if(judge(i-1,k)) ins(i,j,i-1,k);
                }
                fo(k,i+1,n){
                    if(judge(k,j)) ins(i,j,k,j);
                    if(judge(k,j+1)) ins(i,j,k,j+1);
                    if(judge(k,j-1)) ins(i,j,k,j-1);
                }
            }
        }
        
    }
    int findf(int x){
        return x == fa[x] ? x : fa[x] = findf(fa[x]);
    }
    void mst(){
        sort(e+1,e+1+cnt);
        fo(i,1,N-10) fa[i] = i;
        int u,v;
        fo(i,1,cnt){
            u = e[i].u;
            v = e[i].v;
            u = findf(u);
            v = findf(v);
            if(u != v){
                fa[u] = v;
                if(!e[i].w)ans1--;
                if(e[i].w)ans2++;
                ans3 += e[i].w;
            }
        }
        cout<<ans1<<endl<<ans2<<" "<<ans3;
    }
    int main(){
        input();
        build();
        mst();
        return 0;
    } 
  • 相关阅读:
    Pandas学习整理与实践
    数据描述性统计整理
    关于购置硬盘的相关注意点
    福大软工 · 最终作业
    福大软工 · 第十二次作业
    Beta冲刺 (7/7)
    Beta冲刺 (6/7)
    深度剖析Vue中父给子、子给父、兄弟之间传值!
    mysql 增删改插
    前端必学TypeScript之第一弹,st基础类型!
  • 原文地址:https://www.cnblogs.com/hyfer/p/6035592.html
Copyright © 2011-2022 走看看