1 条题解
-
0
自动搬运
来自洛谷,原作者为

daihang
**搬运于
2025-08-24 21:45:01,当前版本为作者最后更新于2020-03-01 22:16:03,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
并查集+最小生成树算法
题目要求最大值最小化,满足最小生成树的性质
Details
1. 建图。除边缘外的每个点均可以向上下左右四个方向连边,点的编号可表示为: n*(i-1)+j (i为行,j为列)
实现代码:
int ex(int i,int j){ return (i-1)*n+j; }边的权值即为两点高度差的绝对值
2. 如何维护集合的大小。初始化将size全设为1,后续再进行合并操作(merge)时,将旧的集合的大小更新到新的集合上。在新的集合大小大于(n*n)/2时,输出当前边的权值即可。
实现代码:
x=find(x);//find函数是为了找父亲 y=find(y); if(x!=y){ fa[x]=y; siz[y]+=siz[x]; if(siz[y]>=(n*n+1)/2){ cout<<w<<endl; return 0; } }3. 最小生成树Kruskal 不解释
不会的可以找模板题P3366 【模板】最小生成树
最后送上代码,祝各位
水题切题愉快#include<bits/stdc++.h> using namespace std; const int maxn=501; int n; int mp[maxn][maxn]; inline int read(){//快读 int x=0,y=1; char ch=getchar(); while(!isdigit(ch)){if(ch=='-')y=-y; ch=getchar();} while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();} return x*y; } int fa[maxn*maxn]; int siz[maxn*maxn]; struct node{ int u,v,w; node(){} node(int uu,int vv,int ww){ u=uu; v=vv; w=ww; } }edge[maxn*maxn*4]; bool cmp(const node &a,const node &b){ return a.w<b.w; } int ans=0; void init(){ for(int i=1;i<=n*n;i++){ fa[i]=i; siz[i]=1; } } int find(int x){ if(x==fa[x]) return x; else return fa[x]=find(fa[x]); } int ex(int i,int j){ return (i-1)*n+j; } int main(){ n=read(); for(int i=1;i<=n;++i){ for(int j=1;j<=n;++j){ mp[i][j]=read(); } } init(); int tp=1; for(int i=1;i<=n;++i){ for(int j=1;j<=n;++j){ if(i>1){ edge[tp]=node(ex(i,j),ex(i-1,j),abs(mp[i-1][j]-mp[i][j])); tp++; } if(j>1){ edge[tp]=node(ex(i,j),ex(i,j-1),abs(mp[i][j-1]-mp[i][j])); tp++; } if(i<n){ edge[tp]=node(ex(i,j),ex(i+1,j),abs(mp[i+1][j]-mp[i][j])); tp++; } if(j<n){ edge[tp]=node(ex(i,j),ex(i,j+1),abs(mp[i][j+1]-mp[i][j])); tp++; } } } sort(edge+1,edge+tp,cmp); for(int i=1;i<tp;i++){ int x=edge[i].u; int y=edge[i].v; int w=edge[i].w; x=find(x); y=find(y); if(x!=y){ fa[x]=y; siz[y]+=siz[x]; if(siz[y]>=(n*n+1)/2){ cout<<w<<endl; return 0; } } } }写题解不易,求个赞
- 1
信息
- ID
- 2137
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者