zoukankan      html  css  js  c++  java
  • codevs 1002 搭桥x

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

    见描述

    分类标签 Tags 

    1)WA了第0个点代码qwq(根本想不到哪里错了):

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    
    using namespace std;
    
    const int M = 5e4 + 233;
    const int S = 51;
    int r,c,num,cnt,ans,sum;//  #building  .空地
    int d[S][S];
    char qq[M];
    bool vis[S][S];
    int f[M];
    int h[8]= {0, 0,1,1, 1,-1,-1,-1}, //8个方向
        z[8]= {1,-1,0,1,-1, 0, 1,-1};
        //右 左 下 右下 左下 上 右上 右下
    
    struct Q {
        int Qx,Qy;
        int v;
        bool operator < (const Q &qwq)const
        {
            return v < qwq.v;
        }
    } a[5000001];
    
    int find(int x)
    { return x == f[x] ? x : f[x] = find(f[x]); }
    
    bool P(int x1,int y1,int x2,int y2,int t)//t为编号
    {
        if(x2<1 || x2>r || y2<1 || y2>c || !d[x2][y2])
            return 1;
        if(d[x1][y1]==d[x2][y2])
            return 0;
        cnt++;
        a[cnt].Qx=d[x1][y1];
        a[cnt].Qy=d[x2][y2];
        a[cnt].v=t-1;
        return 1;
    }
    
    void build(int x,int y)
    {
        for(int i=x+1; i<=r; i++)
            if(!P(x,y,i,y,i-x)
                    ||!P(x,y,i,y+1,i-x)
                    ||!P(x,y,i,y-1,i-x))
                break;
        for(int i=x-1; i>0; i--)
            if(!P(x,y,i,y,x-i)
                    ||!P(x,y,i,y+1,x-i)
                    ||!P(x,y,i,y-1,x-i))
                break;
        for(int i=y+1; i<=c; i++)
            if(!P(x,y,x,i,i-y)
                    ||!P(x,y,x+1,i,i-y)
                    ||!P(x,y,x-1,i,i-y))
                break;
        for(int i=y-1; i>0; i--)
            if(!P(x,y,x,i,y-1)
                    ||!P(x,y,x+1,i,y-i)
                    ||!P(x,y,x-1,i,y-i))
                break;
    }
    
    void ss(int x,int y)
    {
        d[x][y]=num;
        int xx,yy;
        for(int i=0; i<8; i++) //搜索
        {
            xx=x+h[i];
            yy=y+z[i];
            if(vis[xx][yy] && !d[xx][yy])
                ss(xx,yy);
        }
    }
    
    void readin()
    {
        cin>>r>>c;
        for(int i=1; i<=r; i++)
        {
            cin>>qq;
            for(int j=1; j<=c; j++)
                if(qq[j-1]=='#')
                    vis[i][j]=1;
        }
    }
    
    void works()
    {
        for(int i=1; i<=r; i++)
        {
            for(int j=1; j<=c; j++)
            {
                if(vis[i][j] && !d[i][j])
                {
                    num++;
                    ss(i,j);
                }
            }
        }
        cout<<num<<endl;
    
        for(int i=1; i<=r; i++)
            for(int j=1; j<=c; j++)
                if(vis[i][j])
                    build(i,j);
        for(int i=1; i<=num; i++)
            f[i]=i; //初始化
        sort(a+1,a+1+cnt);
        int f1,f2;
        for(int i=1; i<=cnt; i++)
        {
            f1=find(a[i].Qx);
            f2=find(a[i].Qy);
            if(f1!=f2)
            {
                f[f1]=f2;
                ans++;
                sum+=a[i].v;
            }
        }
        cout<<ans<<" "<<sum;
    }
    
    int main()
    {
        readin();
        works();
        return 0;
    }

    2)AC代码:

    #include <iostream>
    #include <algorithm>
    #define maxn 100000
    
    using namespace std;
    
    const int M = 1005;
    const int xx[8] = {0, 0,1,1, 1,-1,-1,-1},
                 yy[8] = {1,-1,0,1,-1, 0, 1,-1};
    int n,m,q[M][M],dad[maxn],cnt,ans,sum;
    bool map[M][M];
    
    struct node {
        int x,y,v;
        bool operator < (const node &qwq)const
        {
            return v < qwq.v;
        }
    } e[maxn];
    
    int getdad(int x)
    { return x == dad[x] ? x : dad[x] = getdad(dad[x]); }
    
    bool input(int x1,int y1,int x2,int y2,int t)
    {
        if(x2<1||x2>n||y2<1||y2>m||!q[x2][y2])
            return 1;
        if(q[x1][y1]==q[x2][y2])
            return 0;
        cnt++;
        e[cnt].x=q[x1][y1];
        e[cnt].y=q[x2][y2];
        e[cnt].v=t-1;
        return 1;
    }
    
    void dfs(int x,int y)
    {
        q[x][y]=ans;
        for(int i=0; i<8; i++)
        {
            int x0=x+xx[i],y0=y+yy[i];
            if(map[x0][y0] && !q[x0][y0])
                dfs(x0,y0);
        }
    }
    
    void build(int x,int y)
    {
        for(int i=x+1; i<=n; i++)
            if(!input(x,y,i,y,i-x)
                    ||!input(x,y,i,y+1,i-x)
                    ||!input(x,y,i,y-1,i-x))
                break;
        for(int i=x-1; i>0; i--)
            if(!input(x,y,i,y,x-i)
                    ||!input(x,y,i,y+1,x-i)
                    ||!input(x,y,i,y-1,x-i))
                break;
        for(int i=y+1; i<=m; i++)
            if(!input(x,y,x,i,i-y)
                    ||!input(x,y,x+1,i,i-y)
                    ||!input(x,y,x-1,i,i-y))
                break;
        for(int i=y-1; i>0; i--)
            if(!input(x,y,x,i,y-1)
                    ||!input(x,y,x+1,i,y-i)
                    ||!input(x,y,x-1,i,y-i))
                break;
    }
    
    void work1()
    {
        ans=0;
        for(int i=1; i<=n; i++)
            for(int j=1; j<=m; j++)
                if(map[i][j] && !q[i][j])
                {
                    ans++;
                    dfs(i,j);
                }
        cout<<ans<<endl;
    }
    
    void work2()
    {
        for(int i=1; i<=n; i++)
            for(int j=1; j<=m; j++)
                if(map[i][j])
                    build(i,j);
        sort(e+1,e+cnt+1);
        for(int i=1; i<=ans; i++)
            dad[i]=i;
        ans=0;
        for(int i=1; i<=cnt; i++)
        {
            int k=getdad(e[i].x);
            int l=getdad(e[i].y);
            if(k!=l)
            {
                dad[k]=l;
                ans++;
                sum+=e[i].v;
            }
        }
        cout<<ans<<' '<<sum;
    }
    
    int main()
    {
        cin>>n>>m;
        for(int i=1; i<=n; i++)
        {
            char a[maxn];
            cin>>a;
            for(int j=1; j<=m; j++)
                if(a[j-1]=='#')
                    map[i][j]=1;
        }
        work1();
        work2();
        return 0;
    }

    如果运气好也是错,那我倒愿意错上加错!

    ❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀

  • 相关阅读:
    机器学习-分类算法-决策树,随机森林10
    机器学习-分类算法-模型选择与调优09
    机器学习-分类算法-精确率和召回率08
    机器学习-分类算法-朴素贝叶斯算法07
    机器学习-分类算法-K-近邻算法06
    java读取自定义配置文件并引用
    kafka发布消息报错LEADER_NOT_AVAILABLE
    Kettle位置参数(Argument)、命名参数(Parameter)、变量(Variable)
    kettle里的两个参数和一个变量
    如何在命令行下运行kettle的作业(job)和转换(transform)
  • 原文地址:https://www.cnblogs.com/zxqxwnngztxx/p/6724130.html
Copyright © 2011-2022 走看看