zoukankan      html  css  js  c++  java
  • bzoj4410 [Usaco2016 Feb] Fence in

    Description

    有一个平面,左下角是(0,0),右上角是(A,B)。
    有n个平行于y轴的栅栏a1..an,表示挡在(ai,0)到(ai,B)之间。
    有m个平行于x轴的栅栏b1..bn,表示挡在(0,bi)到(A,bi)之间。
    这样,平面被划成了(n+1)*(m+1)块。
    现在要去掉某些栅栏的一部分,使得每一块都连通。
    比如原来是这样:

    可以去掉后变成这样:

    求最少需要去掉多少长度的栅栏使得每一块都连通。

    Input

    第一行四个数A,B,n,m。
    A<=1000000000 ,B<=1000000000 N<=25000 M<=25000
    接下来n行每行一个数表示ai
    接下来m行每行一个数表示bi。
    0<ai<A  0<bi<B 

    Output

    输出一个数表示答案。
     
    对边长排序后从小到大加边求最小生成树,一次加边加一行或一列,注意由于一部分可能已经连通,加边时要减去不需要加的边。
    时间复杂度O(nlogn+mlogm+n+m)
    #include<cstdio>
    #include<algorithm>
    int A,B,n,m;
    int ns[25005],ms[25005];
    int pn=0,pm=0;
    long long ans=0;
    inline int read(){
        int x=0,c=getchar();
        while(c>'9'||c<'0')c=getchar();
        while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
        return x;
    }
    int main(){
        A=read();B=read();n=read();m=read();
        ns[0]=ms[0]=0;
        ns[n+1]=B;
        ms[m+1]=A;
        for(int i=1;i<=n;i++)ns[i]=read();
        for(int i=1;i<=m;i++)ms[i]=read();
        std::sort(ns,ns+n+2);
        std::sort(ms,ms+m+2);
        for(int i=0;i<=n;i++)ns[i]=ns[i+1]-ns[i];
        for(int i=0;i<=m;i++)ms[i]=ms[i+1]-ms[i];
        n++;m++;
        std::sort(ns,ns+n);
        std::sort(ms,ms+m);
        while(pn<n&&pm<m){
            if(ns[pn]<ms[pm])ans+=ns[pn]*1ll*(pm&&pn?m-pm:m-1),pn++;
            else ans+=ms[pm]*1ll*(pn&&pm?n-pn:n-1),pm++;
        }
        while(pn<n)ans+=ns[pn]*1ll*(pm&&pn?m-pm:m-1),pn++;
        while(pm<m)ans+=ms[pm]*1ll*(pn&&pm?n-pn:n-1),pm++;
        printf("%lld
    ",ans);
        return 0;
    }

     

  • 相关阅读:
    【洛谷P3649】回文串
    【CH2401】送礼物
    Python 函数
    Python 文件操作
    JS的DOM和BOM
    JavaScript (内置对象及方法)
    JavaScript 基础(数据类型、函数、流程控制、对象)
    Python基础数据类型(数字、字符串、布尔、列表、元组、字典、集合等)
    MySQL(二)
    数据备份 及 Python 操作 Mysql
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5239834.html
Copyright © 2011-2022 走看看