zoukankan      html  css  js  c++  java
  • P5930 [POI1999]降水

    P5930 [POI1999]降水

    虽然是1999年的题了,但是还挺值得一做,因为它使我发现我完全不会并查集,想了好久,甚至这种1k的代码都写挂了

    这题目如果值域再大估计就要搜索了,然而在tg混久了发现不会搜索了,但是值域只有 (10000)

    这使我们容易联想到维护每个高度上的横截面面积,然后从小到大扫一遍每个截面

    考虑用并查集维护连通性(同时维护每个集合的大小)

    (0) 下标表示与外界联通,即不能放水。那么 (siz[find(0)]) 就是这个截面非土地部分不能放水的面积

    开个变量统计一下当前截面非土地部分面积即可

    目前是洛谷最优解(要开O2),话说是不是我因为维护了集合大小然后自己胡了个启发式合并+路径压缩的并查集上去qwq

    另外,我怀疑这五个点是一样的,因为我WA过,RE过,AC过,五个点的状态一样,运行时间大致相同,WA的时候返回的详细信息都相同

    时间复杂度 (O(V+nmalpha))

    #include<bits/stdc++.h>
    using namespace std;
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')f=0;ch=getchar();}
    	while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    	return f?x:-x;
    }
    #define N 105
    int n,m,a[N][N],now,ans,H;
    int F[N*N],siz[N*N];
    #define id(x,y) ((x-1)*m+y)
    vector<pair<int,int> >v[10005];
    #define pb push_back
    #define x first
    #define y second
    #define mkp make_pair
    int find(int x){return x==F[x]?x:F[x]=find(F[x]);}
    void merge(int x,int y){
    	x=find(x),y=find(y);
    	if(x==y)return;
    	if(siz[x]<siz[y])F[x]=y,siz[y]+=siz[x];
    	else F[y]=x,siz[x]+=siz[y];
    }
    signed main(){
    	n=read(),m=read();
    	for(int i=1;i<=n;++i)
    		for(int j=1;j<=m;++j)
    			v[a[i][j]=read()].pb(mkp(i,j)),H=max(H,a[i][j]);
    	for(int i=1,mx=n*m;i<=mx;++i)F[i]=i,siz[i]=1;
    	for(int i=1;i<=H;++i){
    		for(pair<int,int> j:v[i]){
    			int x=j.x,y=j.y;++now;
    			if(x==1||x==n||y==1||y==m)merge(id(x,y),0);
    			if(y>1&&a[x][y-1]<=a[x][y])merge(id(x,y),id(x,y-1));
    			if(x>1&&a[x-1][y]<=a[x][y])merge(id(x,y),id(x-1,y));
    			if(y<m&&a[x][y+1]<=a[x][y])merge(id(x,y),id(x,y+1));
    			if(x<n&&a[x+1][y]<=a[x][y])merge(id(x+1,y),id(x,y));
    		}
    		ans+=now-siz[find(0)];
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
    路漫漫其修远兮,吾将上下而求索
  • 相关阅读:
    Example of Formalising a Grammar for use with Lex & Yacc
    TCL脚本语言基础介绍
    linux环境下的c++编程
    如何利用FPGA进行时序分析设计
    可移植的配置visual studio工程第三方库
    [转]windows10 1703 鼠标右键打开命令提示符cmd
    重载和const形参的学习心得
    华为codecraft2018总结
    【转】C/C++使用心得:enum与int的相互转换
    C++学习笔记1-使用数组进行vector初始化
  • 原文地址:https://www.cnblogs.com/zzctommy/p/13869725.html
Copyright © 2011-2022 走看看