【Usaco2016 FEB】Fenced In 题解
2016-03-02 13:49
218 查看
题目
[code]Farmer John has realized that many of his cows are strangely agoraphobic (being fearful of large open spaces). To try and make them less afraid of grazing, he partitions his large field into a number of smaller regions by building vertical (north-south) and horizontal (east-west) fences. The large field is a rectangle with corner points at (0,0) and (A,B). FJ builds n vertical fences (0≤n≤25,000) at distinct locations a1…an (0<ai<A); each fence runs from (ai,0) to (ai,B). He also builds m horizontal fences (0≤m≤25,000) at locations b1…bm (0<bi<B); each such fence runs from (0,bi) to (A,bi). Each vertical fence crosses through each horizontal fence, subdividing the large field into a total of (n+1)(m+1) regions. Unfortunately, FJ completely forgot to build gates into his fences, making it impossible for cows to leave their enclosing region and travel around the entire field! He wants to remedy this situation by removing pieces of some of his fences to allow cows to travel between adjacent regions. He wants to select certain pairs of adjacent regions and remove the entire length of fence separating them; afterwards, he wants cows to be able to wander through these openings so they can travel anywhere in his larger field. For example, FJ might take a fence pattern looking like this: +---+--+ | | | +---+--+ | | | | | | +---+--+ and open it up like so: +---+--+ | | +---+ + | | | | +---+--+ Please help FJ determine the minimum total length of fencing he must remove to accomplish his goal. 有一个平面,左下角是(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 The first line of input contains A, B, n, and m (1≤A,B≤1,000,000,000). The next n lines contain a1…an, and the next m lines after that contain b1…bm .第一行四个数A,B,n,m。 接下来n行每行一个数表示ai 接下来m行每行一个数表示bi。 0<ai<A 0<bi<B Output Please write the minimum length of fencing FJ must remove. Note that this might be too large to fit into a standard 32-bit integer, so you may need to use 64-bit integer types (e.g., "long long" in C/C++). 输出一个数表示答案。
略微分析
有点像最小生成树,但空间不允许。画个图自己推理一下,很好找到规律。
提示:1.考虑一行一行(一列一列)的开。
2.参考Kruskal算法的思想
然后自己推吧。。。。。。。。。。。
代码
[code]#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<vector> #define ll long long #define int long long using namespace std; const int maxn=25000+10; const int inf=2000000001; int A,B,n,m; ll xl[maxn],yl[maxn],lenx[maxn],leny[maxn],cx=0,cy=0; //cx,cy表示平行于x,y轴切了的个数 ll ans=0,num=0,S; main() { cin>>A>>B>>n>>m; for(int i=0;i<n;i++) scanf("%I64d",&xl[i]);//有n个平行于y轴的栅栏a1..an,表示挡在(ai,0)到(ai,B)之间 for(int i=0;i<m;i++) scanf("%I64d",&yl[i]);//有m个平行于x轴的栅栏b1..bn,表示挡在(0,bi)到(A,bi)之间 S=(n+1)*(m+1)-1; sort(xl,xl+n); sort(yl,yl+m); lenx[0]=xl[0];lenx =A-xl[n-1]; for(int i=1;i<n;i++) lenx[i]=xl[i]-xl[i-1]; sort(lenx,lenx+n+1); leny[0]=yl[0];leny[m]=B-yl[m-1]; for(int i=1;i<m;i++) leny[i]=yl[i]-yl[i-1]; sort(leny,leny+m+1); while(num<S) { int x,y,xi,yi; x=lenx[cx];xi=cx;y=leny[cy];yi=cy; if(x<y) { if(cy>=2&&cx>=1) num+=m-(cy-1),ans+=x*(m-(cy-1)); else num+=m,ans+=x*m; //xch[xi]=true; cx++; } else { if(cx>=2&&cy>=1)num+=1ll*n-1ll*(cx-1),ans+=1ll*y*1ll*(n-(cx-1)); else num+=1ll*n,ans+=1ll*y*n; //ych[yi]=true; cy++; } } printf("%I64d",ans); return 0; }
本体的其他推荐:
这里
相关文章推荐
- html页面,手机模拟器不能滑动,但是鼠标能滚动
- HTML文档类型说明
- JSTL 核心标签库 使用
- fastjson对Date的处理
- JavaScript 获取当前时间戳
- 浅谈href=#与href=javascript:void(0)的区别
- CodePen's CSS
- 操作checkbox复选框问题
- JS中取消事件的两种方式
- input 双击后不出现历史记录
- 《AngularJS》5个实例详解Directive(指令)机制
- 前端资源大收集
- 提升用户体验之A/B测试(3)——sixpack-js客户端
- 在Windows上安装Node.js模块的方法
- 关于Java 中回调函数的一些理解及与JavaScript的对比
- ng-messages AngularJs 表单校验方式
- 《AngularJS高级程序设计》学习笔记
- javascript笔记——js面试问题
- javascript 高级程序设计 一
- jQuery相关知识总结