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;
}

 

posted @ 2023-09-03 13:14  JMXZ  阅读(107)  评论(0)    收藏  举报