求调
  • 板块P2170 选学霸
  • 楼主RayKai
  • 当前回复0
  • 已保存回复0
  • 发布时间2025/7/23 00:50
  • 上次更新2025/7/23 12:28:36
查看原帖
求调
1726976
RayKai楼主2025/7/23 00:50
#include<iostream>
#include<cmath>
using namespace std;
int dp[40005],height[20005],s[20005],p[20005],f[20005],n,m,k;
int find(int x){
    if(x!=s[x])s[x]=find(s[x]);
    return s[x];
}

int main(){
    cin>>n>>m>>k;
    for(int i=1;i<=n;i++){
        s[i]=i;
        p[i]=1;
    }
    for(int i=1;i<=k;i++){
        int x,y;
        cin>>x>>y;
        x=find(x);y=find(y);
        if(height[x]==height[y]){
            height[x]++;
            s[y]=x;
            p[x]+=p[y];
        }else{
            if(height[x]>height[y]){
                s[y]=x;
                p[x]+=p[y];
            }else{
                s[x]=y;
                p[y]+=p[x];
            }
        }
    }
    int tot=0;
    for(int i=1;i<=m;i++){
        if(s[i]==i){
            tot++;
            f[tot]=p[i];
        }
    }
    for(int i=1;i<=tot;i++){
        for(int j=2*m;j>=f[i];j--)dp[j]=max(dp[j],dp[j-f[i]]+f[i]);
    }
    int minn=0x3f3f3f3f,ans=0x3f3f3f3f;
    for(int i=1;i<=2*m;i++){
        if(minn>abs(dp[i]-m)){
            minn=abs(dp[i]-m);
            ans=dp[i];
        }
    }
    if(ans==0x3f3f3f3f)cout<<0;
    else cout<<ans;
    return 0;
}
2025/7/23 00:50
加载中...