首先将每个平原缩成一个点,建出图,相邻两个点之间的边权为它们高度的较小值。

用Kruskal算法求出这个图的最大生成树,每次合并两个连通块时新建一个点指向它们,得到一棵有根树。

对于每个点,求出它子树内最高的峰,那么对于每个叶子,在它到根的路径上二分查找即可。

时间复杂度$O(nm\log(nm))$。

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=2005,M=200010;
int n,m,i,j,x,y,z,dx,dy,a[N][N],p[N][N],cb;
int cnt,is[M],h[M],f[M],son[M][2],ma[M],q[M],top,ans;
struct P{int x,y;P(){}P(int _x,int _y){x=_x,y=_y;}}b[M/2],fin[M/2];
inline bool cmp(const P&x,const P&y){return a[x.x][x.y]>a[y.x][y.y];}
inline bool cmp2(const P&a,const P&b){return a.x==b.x?a.y>b.y:a.x>b.x;}
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
void dfs(int x,int y){
p[x][y]=cnt;
for(int i=x-1;i<=x+1;i++)for(int j=y-1;j<=y+1;j++){
if(a[i][j]>a[x][y])is[cnt]=0;
if(a[i][j]==a[x][y]&&!p[i][j])dfs(i,j);
}
}
int F(int x){return f[x]==x?x:f[x]=F(f[x]);}
inline void merge(int x,int y,int z){
if(!x||!y)return;
x=F(x),y=F(y);
if(x==y)return;
h[++cnt]=z,f[cnt]=cnt;
son[cnt][0]=x,son[cnt][1]=y;
f[x]=f[y]=cnt;
}
void dfs2(int x){
if(is[x])ma[x]=h[x];
for(int i=0;i<2;i++){
int y=son[x][i];
if(!y)continue;
dfs2(y);
ma[x]=max(ma[x],ma[y]);
}
}
inline void cal(int o){
int l=1,r=top,t=0,mid;
while(l<=r)if(ma[q[mid=(l+r)>>1]]>o)l=(t=mid)+1;else r=mid-1;
fin[++ans]=P(o,h[q[t]]);
}
void dfs3(int x){
if(is[x])cal(h[x]);
q[++top]=x;
for(int i=0;i<2;i++){
int y=son[x][i];
if(!y)continue;
dfs3(y);
}
top--;
}
int main(){
read(n),read(m);
for(i=1;i<=n;i++)for(j=1;j<=m;j++)read(a[i][j]);
for(i=1;i<=n;i++)for(j=1;j<=m;j++)if(!p[i][j])is[++cnt]=1,h[cnt]=a[i][j],dfs(i,j);
for(i=1;i<=n;i++)for(j=1;j<=m;j++)b[++cb]=P(i,j);
sort(b+1,b+cb+1,cmp);
for(i=1;i<=cnt;i++)f[i]=i;
for(i=1;i<=cb;i++){
x=b[i].x,y=b[i].y,z=p[x][y];
for(dx=x-1;dx<=x+1;dx++)for(dy=y-1;dy<=y+1;dy++)if(a[dx][dy]>=a[x][y])merge(p[dx][dy],z,a[x][y]);
}
dfs2(cnt),dfs3(cnt);
sort(fin+1,fin+ans+1,cmp2);
printf("%d\n",ans);
for(i=1;i<=ans;i++)printf("%d %d\n",fin[i].x,fin[i].y);
return 0;
}

  

BZOJ3485 : [Baltic2012]peaks的更多相关文章

  1. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  2. 【BZOJ-3545&3551】Peaks&加强版 Kruskal重构树 + 主席树 + DFS序 + 倍增

    3545: [ONTAK2010]Peaks Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1202  Solved: 321[Submit][Sta ...

  3. *[codility]Peaks

    https://codility.com/demo/take-sample-test/peaks http://blog.csdn.net/caopengcs/article/details/1749 ...

  4. Clustering by density peaks and distance

    这次介绍的是Alex和Alessandro于2014年发表在的Science上的一篇关于聚类的文章[13],该文章的基本思想很简单,但是其聚类效果却兼具了谱聚类(Spectral Clustering ...

  5. Science论文"Clustering by fast search and find of density peaks"学习笔记

    "Clustering by fast search and find of density peaks"是今年6月份在<Science>期刊上发表的的一篇论文,论文中 ...

  6. bzoj 3545&&3551: [ONTAK2010]Peaks &&加强版 平衡树&&并查集合并树&&主席树

    3545: [ONTAK2010]Peaks Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 635  Solved: 177[Submit][Stat ...

  7. BZOJ 3545: [ONTAK2010]Peaks( BST + 启发式合并 + 并查集 )

    这道题很好想, 离线, 按询问的x排序从小到大, 然后用并查集维护连通性, 用平衡树维护连通块的山的权值, 合并就用启发式合并.时间复杂度的话, 排序是O(mlogm + qlogq), 启发式合并是 ...

  8. bzoj 3551: [ONTAK2010]Peaks加强版

    Description [题目描述]同3545 Input 第一行三个数N,M,Q. 第二行N个数,第i个数为h_i 接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径. 接下来 ...

  9. BZOJ 3551: [ONTAK2010]Peaks加强版 [Kruskal重构树 dfs序 主席树]

    3551: [ONTAK2010]Peaks加强版 题意:带权图,多组询问与一个点通过边权\(\le lim\)的边连通的点中点权k大值,强制在线 PoPoQQQ大爷题解传送门 说一下感受: 容易发现 ...

随机推荐

  1. 苹果应用 Windows 申请 普通证书 和Push 证书 Hbuilder 个推

    最近使用Hbuilder 进行了HTML5开发,因为 HTML5 可以放在android 机器上,也可以放到 IOS机器上,所以很感兴趣,于是开发了一个小应用, 不过问题接着来了: 图1 如图所示:当 ...

  2. Android Native jni 编程入门

    在某些情况下,java编程已经不能满足我们的需要,比如一个复杂的算法处理,这时候就需要用到jni(java native interface)技术: jni 其实就是java和c/cpp之间进行通信的 ...

  3. Xcode因为证书问题经常报的那些错

    去开始做 iOS开发的时候,因为证书问题 Xcode 经常报这样或那样的错,经过实践,现在看见 Xcode 报错已经心平气和了,经常报的错就那么多,整理一下. 1. 确认下证书是不是开发证书,如果是发 ...

  4. 使用HttpWebRequest发送自定义POST请求

    平时用浏览器看网页的时候,点击一下submit按钮的时候其实就是给服务器发送了一个POST请求.但是如何在自己的C#程序里面实现类似的功能呢?本文给出了一个简单的范例,可以实现类似的和web serv ...

  5. WebService - 怎样提高WebService性能 大数据量网络传输处理

    直接返回DataSet对象 返回DataSet对象用Binary序列化后的字节数组 返回DataSetSurrogate对象用Binary序列化后的字节数组 返回DataSetSurrogate对象用 ...

  6. C#关键字ref和out

    using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Di ...

  7. Delphi之DLL知识学习4---创建DLL

    下面是在Delphi中创建一个DLL的全过程,你将看到怎样创建一个接口单元,使之可以被其他的应用程序访问.并且将学会怎么把Delphi的窗体加入DLL中. 一.数美分:一个简单的DLL 下面是包含一个 ...

  8. HDU5792 World is Exploding(树状数组)

    一共6种情况,a < b且Aa < Ab, c < d 且Ac > Ad,这两种情况数量相乘,再减去a = c, a = d, b = c, b = d这四种情况,使用树状数组 ...

  9. 严重: End event threw exception java.lang.IllegalArgumentException: Can't convert argument: null

    堆栈信息: 2014-6-17 10:33:58 org.apache.tomcat.util.digester.Digester endElement 严重: End event threw exc ...

  10. mac os x10.10 安装thrift

    http://thrift.apache.org/docs/install/ 一:安装最新版(自动安装) 最简单的是用homebrew进行安装 安装homebrew 在终端输入ruby -e &quo ...