codevs 1002 搭橋 題解報告

繼續我的刷題之路。。。

*題目描述 Description
有一矩形區域的城市中建築了若干建築物,如果某兩個單元格有一個點相聯繫,則它們屬於同一座建築物。現在想在這些建築物之間搭建一些橋樑,其中橋樑只能沿着矩形的方格的邊沿搭建,如下圖城市1有5棟建築物,可以搭建4座橋將建築物聯繫起來。城市2有兩座建築物,但不能搭建橋樑將它們連接。城市3只有一座建築物,城市4有3座建築物,可以搭建一座橋樑聯繫兩棟建築物,但不能與第三座建築物聯繫在一起。
輸入描述 Input Description
在輸入的數據中的第一行包含描述城市的兩個整數r 和c, 分別代表從北到南、從東到西的城市大小(1 <= r <= 50 and 1 <= c <= 50). 接下來的r 行, 每一行由c 個(“#”)和(“.”)組成的字符. 每一個字符表示一個單元格。“#”表示建築物,“.”表示空地。

輸出描述 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
見描述*

噫。
首先,dfs求聯通塊,just like 球細胞個數
v[][]表示每個點所在聯通塊的編號;

考慮對於每個點,有12個方向上的點可以鏈接。
所以,枚舉這條直線上所有點
b[][]表示兩個聯通塊之間最短的邊

之後跑克魯斯卡爾
求最小生成樹;

得到答案~!~!~!~

代碼!:~

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<stack>
#include<cstdlib>
#include<string>
#include<bitset>
#include<iomanip>
#include<deque>
#define INF 1000000000
#define fi first
#define se second
#define N 100005
#define P 1000000007
#define debug(x) cerr<<#x<<"="<<x<<endl
#define MP(x,y) make_pair(x,y)
using namespace std;
int n,m,a[51][51],v[1001][1001],f[1001],ans=0;
int b[1001][1001];
int kk=1;
int fx[9]={0,1,1,1,-1,-1,-1,0,0};
int fy[9]={0,1,0,-1,1,0,-1,1,-1};
int find(int x)
{
    return x==f[x] ? x:f[x]=find(f[x]);
}
struct zqm
{
    int x,y,s;

}q[100001];
inline int get_num()
{
int num = 0;
char c;
bool flag = false;
while ((c = getchar()) == ' ' || c == '\n' || c == '\r');
if (c == '-') flag = true;
else num = c - '0';
while (isdigit(c = getchar()))
num = num * 10 + c - '0';
return (flag ? -1 : 1) * num;
} //忽略這一堆沒用的讀入優化
void dfs(int x,int y)
{
    for(int i=1;i<=8;i++)
    {
        int tx=x+fx[i],ty=y+fy[i];
        if(!v[tx][ty]&&a[tx][ty]&&tx>0&&tx<=n&&ty>0&&ty<=m)
        {
            v[tx][ty]=kk;
            dfs(tx,ty);
        }
    }
}
bool cmp(zqm a ,zqm b)
{
    return a.s<b.s;
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            char c;
            cin>>c;
            if(c=='.')a[i][j]=0;
            else a[i][j]=1;
        }
    }

    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(!v[i][j]&&a[i][j])
            {
                v[i][j]=kk;
                dfs(i,j);
                kk++; 
            }

        }
    } 
    kk--;
    cout<<kk;
    cout<<endl;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            for(int k=i-2;k>=1;k--)
            {
                for(int l=j-1;l<=j+1;l++)
                {
                    if(b[v[i][j]][v[k][l]]==0)
                    {
                        b[v[i][j]][v[k][l]]=1000;
                    }
                    b[v[i][j]][v[k][l]]=min(b[v[i][j]][v[k][l]],i-k-1);
                    b[v[k][l]][v[i][j]]=b[v[i][j]][v[k][l]];
                }
            }
            for(int k=i+2;k<=n;k++)
            {
                for(int l=j-1;l<=j+1;l++)
                {
                    if(b[v[i][j]][v[k][l]]==0)
                    {
                        b[v[i][j]][v[k][l]]=1000;
                    }
                    b[v[i][j]][v[k][l]]=min(b[v[i][j]][v[k][l]],k-i-1);
                    b[v[k][l]][v[i][j]]=b[v[i][j]][v[k][l]];
                }
            }
            for(int k=i-1;k<=i+1;k++)
            {
                for(int l=1;l<=j-2;l++)
                {
                    if(b[v[i][j]][v[k][l]]==0)
                    {
                        b[v[i][j]][v[k][l]]=1000;
                    }
                    b[v[i][j]][v[k][l]]=min(b[v[i][j]][v[k][l]],j-l-1);
                    b[v[k][l]][v[i][j]]=b[v[i][j]][v[k][l]];
                }
            }
            for(int k=i-1;k<=i+1;k++)
            {
                for(int l=j+2;l<=m;l++)
                {
                    if(b[v[i][j]][v[k][l]]==0)
                    {
                        b[v[i][j]][v[k][l]]=1000;
                    }
                    b[v[i][j]][v[k][l]]=min(b[v[i][j]][v[k][l]],l-j-1);
                    b[v[k][l]][v[i][j]]=b[v[i][j]][v[k][l]];
                }
            }
        }
    }
    int p=0;
    /*for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            cout<<v[i][j]<< " ";
        }cout<<endl;
    }*/ 
    for(int i=1;i<=kk;i++)
    {
        for(int j=1;j<=kk;j++)
        {
            //cout<<b[i][j]<< " ";
            p++;
            q[p].x=i;
            q[p].y=j;
            q[p].s=b[i][j];
        }//cout<<endl;
    }
    sort(q+1,q+1+p,cmp);
    for(int i=1;i<=kk;i++)
    {
        f[i]=i;
    }
    int  pp=kk; 
    for(int i=1;i<=p;i++)
    {
        if(q[i].s&&find(f[q[i].x])!=find(f[q[i].y]))
        {
            kk--;
            ans+=q[i].s;
            f[find(q[i].x)]=find(f[q[i].y]);
            if(kk==1)
            {
                break;
            }
        }
    }
    cout<<pp-kk<< " "<<ans<<endl;
}

噫////

話說爲啥我上傳不了圖片。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章