1 条题解

  • 0
    @ 2026-1-27 19:50:15
    #include<bits/stdc++.h> 
    using namespace std;
    int n,m,k;
    int arr[20100];
    int brr[20100]; 
    int find(int x){ 
    	if(arr[x]==x){//5、自己是自己的父亲结点 
    		return x;
    	}else{
    		return find(arr[x]);//6、如果自己不是自己的父亲结点,利用现在的父亲结点向上寻找最大的父亲结点 
    	}
    } 
    
    
    void unite(int a,int b){
    	//4、寻找a和b的父亲结点 
    	a=find(a);
    	b=find(b);
    	//7、合并,把层数低到合并到层数高的中这样,层数就不需要变化,所以需要额外的一个数组记录层数 
    	if(brr[a] < brr[b]){
    		arr[a]=b;
    		brr[b]+=brr[a]; 
    	}else if(brr[a] > brr[b]){
    		arr[b]=a;
    		brr[a]+=brr[b]; 
    	}else{
    		arr[b]=a;//8、如果两个集合层数相同,把b合到a中,a的层数+1 
    		brr[a]+=brr[b]; 
    	}
    	
    }
    int main() {
        cin>>n>>m>>k;
        //1.初始化,每个人的父亲结点都是他自己 
    	for(int i=0;i<n;i++){
    		arr[i]=i;
    		brr[i]=1;
    	}
    	
    	//2.为每个数据寻找父亲结点
    	int a,b;
    	for(int i=1;i<=k;i++){
    		cin>>a>>b;
    		unite(a,b);//3.a和b的区间进行合并 
    	} 
    	
    	int crr[20100]={};//9、把每个根节点的人数分给每个子节点
    	for(int i=1;i<=n;i++){
    		int a=find(i);
    		crr[i]=brr[a];
    	}
    	
     
    	int min=n+1,c=0;
    	for(int i=1;i<=n;i++){
    		if(abs(crr[i]-m) < min){
    			min=abs(crr[i]-m);
    			c=crr[i];
    		}
    		if(abs(crr[i]-m) == min){
    			if(crr[i] < min) abs(crr[i]-m);
    		}
    	}
    	cout<<c;
        return 0;
    }
    
    • 1

    信息

    ID
    1360
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者