zoukankan      html  css  js  c++  java
  • wikioi 1002 旁路

    意甲冠军:这个问题刚开始的问题,有错误的含义,原桥始建于一条直线。无论多么遥远。

    思维:dfs寻求答案的第一个问题。然后做最小生成树,双方不能大桥将设置INF即可了。然后假设用到INF的边就加上0即可了。这样跑一遍最小生成树就是答案。

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<map>
    #include<queue>
    #include<set>
    #include<cmath>
    #include<bitset>
    #define mem(a,b) memset(a,b,sizeof(a))
    #define lson i<<1,l,mid
    #define rson i<<1|1,mid+1,r
    #define llson j<<1,l,mid
    #define rrson j<<1|1,mid+1,r
    #define INF 0x7fffffff
    #define maxn 55
    typedef long long ll;
    typedef unsigned long long ull;
    using namespace std;
    int n,m,cnt,vis[maxn][maxn],mm[maxn][maxn],sum;
    int a[1000005],b[1000005],tmp,sum2,sum3;
    char s[maxn][maxn];
    int dist[8][2]= {1,0,1,1,1,-1,0,1,0,-1,-1,0,-1,1,-1,-1};
    int f[1000005];
    void dfs(int x,int y,int ans)
    {
        for(int i=0; i<8; i++)
        {
            int xx=x+dist[i][0],yy=y+dist[i][1];
            if(xx>=0&&xx<n&&yy>=0&&yy<m&&!vis[xx][yy]&&s[xx][yy]=='#')
            {
                vis[xx][yy]=1;
                f[mm[xx][yy]]=f[ans];
                dfs(xx,yy,ans);
            }
        }
    }
    int find(int x)
    {
        return f[x]==x?x:f[x]=find(f[x]);
    }
    struct abc
    {
        int u,v,w;
        bool operator<(const abc &a)const
        {
            return w<a.w;
        }
    } e[1000005];
    void kruscal()
    {
        sort(e,e+tmp);
        int sum=1;
        for(int i=0; i<tmp&&sum!=cnt; i++)
        {
            int x=find(e[i].u),y=find(e[i].v);
            if(x!=y)
            {
                sum++;
                sum3+=(e[i].w==INF?0:e[i].w);
                sum2++;
                f[x]=y;
            }
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=0; i<n; i++)
            scanf("%s",s[i]);
        mem(vis,0);
        cnt=tmp=0;
        mem(f,0);
        mem(mm,0);
        int sum1=0;
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
                if(s[i][j]=='#')
                {
                    mm[i][j]=++cnt;
                    a[cnt]=i,b[cnt]=j;
                    f[cnt]=cnt;
                }
        for(int i=1; i<=cnt; i++)
            for(int j=i+1; j<=cnt; j++)
            {
                e[tmp].u=i,e[tmp].v=j;
                if(abs(a[i]-a[j])<=1&&abs(b[i]-b[j])<=1)
                    e[tmp++].w=0;
                else if(abs(a[i]-a[j])<=1)
                    e[tmp++].w=abs(b[i]-b[j])-1;
                else if(abs(b[i]-b[j])<=1)
                    e[tmp++].w=abs(a[i]-a[j])-1;
                else e[tmp++].w=INF;
            }
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
                if(s[i][j]=='#'&&!vis[i][j])
                {
                    vis[i][j]=1;
                    dfs(i,j,mm[i][j]);
                    sum1++;
                }
        kruscal();
        printf("%d
    %d %d
    ",sum1,sum2,sum3);
        return 0;
    }
    


  • 相关阅读:
    nullnullUVa 10066 The Twin Towers(LCS水题)
    代码错误zoj1298Domino Effect
    实现图形Qt学习:三维绘图之OpenGL和Qt的结合
    情况数组zoj2412Farm Irrigation
    nullnulle人事管理系统人事档案变更管理人员合同变更
    判断条件UVa 10192 Vacation(LCS水题)
    查询数量查看表的所有相关列信息
    代码提交省赛啊省赛
    输入声音如何搜索一张发音的图片
    数组字符串uva 10405 Longest Common Subsequence(最长公共子序列)
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5018315.html
Copyright © 2011-2022 走看看