P5687 [CSP-S2019 江西] 网格图
》》》求 方格里 的最小生成树
》》》kruscal 但是排序nlog2n 但重复太多

if(a[p1]<b[p2])ans+=(1ll*a[p1++]*(m-h)),l++,sum+=(m-h); -》不构成环 的最大边数
树<-不构成环+m-1条边
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <algorithm> #include <cmath> #include <vector> #include <set> #include <map> #include <stdlib.h> #include <stack> #include <queue> #define ri register int #define N 300005 #define M 90000005 inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f; } struct node{ int q,z,b; }edge[M]; int f[M],n,m,cnt=0,suma=0,sumb=0; long long ans=0; int d; bool cmp(node x,node y){ return x.b<y.b; } int get(int p){ if(f[p]==p)return p; return f[p]=get(f[p]); } int main(){ n=read(),m=read();d=n*m-1; for(ri i=1;i<=n;i++){ int w=read(),q=(i-1)*m+1,z=q+1; for(ri j=1;j<m;j++){ edge[++cnt].b=w,edge[cnt].q=q,edge[cnt].z=z; q+=1,z+=1; } } for(ri i=1;i<=m;i++){ int w=read(),q=i,z=i+m; for(ri j=1;j<n;j++){ edge[++cnt].b=w,edge[cnt].q=q,edge[cnt].z=z; q+=m,z+=m; } } for(ri i=1;i<=d+1;i++)f[i]=i; std::sort(edge+1,edge+cnt+1,cmp); while(true){ int x=edge[++sumb].q,y=edge[sumb].z; if(get(x)!=get(y)){ suma++; ans+=(long long)edge[sumb].b; f[get(x)]=get(y); } if(suma==d)break; } printf("%lld",ans); return 0; }
#include<cstdio> #include<iostream> #include<algorithm> //#include<queue> //#include<vector> //#include<bits/stdc++.h> #define ll long long #define ddd printf("-----------------------\n"); using namespace std; const int maxn=3e5+10 ; int n,m,a[maxn],b[maxn],p1=2,p2=2,l=1,h=1,sum; ll ans; int main() { ios::sync_with_stdio(false); cin>>n>>m; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=m;i++) cin>>b[i]; sort(a+1,a+1+n); sort(b+1,b+1+m); ans=1ll*a[1]*(m-1)+1ll*b[1]*(n-1),sum+=m+n-2; for(;;) { if(a[p1]<b[p2]) ans+=1ll*a[p1++]*(m-l),h++,sum+=(m-l); else ans+=1ll*b[p2++]*(n-h),l++,sum+=n-h; if(sum==n*m-1) break; } cout<<ans<<'\n'; return 0; }

浙公网安备 33010602011771号