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;
}

 

posted @ 2017-04-17 18:10  夜雨声不烦  阅读(228)  评论(0编辑  收藏  举报