1 条题解

  • 0
    @ 2026-2-18 15:57:47
    #include<bits/stdc++.h>
    using namespace std;
    
    // [1] 全局常量:最大人数限制,适配题目N,M≤10000的范围
    const int MAXN = 10010;
    
    // [2] 男性并查集数组:A公司(男性,正数编号)的父节点数组
    int fa_male[MAXN];
    // [3] 男性并查集深度数组:用于按秩合并优化
    int dep_male[MAXN];
    
    // [4] 女性并查集数组:B公司(女性,负数编号)的父节点数组,存储绝对值后的编号
    int fa_female[MAXN];
    // [5] 女性并查集深度数组:用于按秩合并优化
    int dep_female[MAXN];
    
    // 函数声明
    int find_male(int x);
    void unite_male(int x, int y);
    int find_female(int x);
    void unite_female(int x, int y);
    
    // [6] 主函数:程序运行入口
    int main()
    {
        int N, M, P, Q;
        cin >> N >> M >> P >> Q; // [7] 读入A公司人数N、B公司人数M、男性朋友关系数P、女性朋友关系数Q
        
        // [8] 初始化男性并查集
        for(int i = 1; i <= N; i++)
        {
            fa_male[i] = i; // [9] 每个男性初始独立为一个集合,父节点设为自身
            dep_male[i] = 1; // [10] 每个集合的初始树深度设为1
        }
        
        // [11] 处理P条男性朋友关系
        for(int i = 1; i <= P; i++)
        {
            int X, Y;
            cin >> X >> Y; // [12] 读入男性朋友的两个编号
            // [13] 调用男性并查集合并函数,跳转至该函数完成注释
            unite_male(X, Y);
        }
        
        // [20] 回到主函数,男性关系处理完成
        // [21] 初始化女性并查集
        for(int i = 1; i <= M; i++)
        {
            fa_female[i] = i; // [22] 每个女性初始独立为一个集合,父节点设为自身(编号取绝对值)
            dep_female[i] = 1; // [23] 每个集合的初始树深度设为1
        }
        
        // [24] 处理Q条女性朋友关系
        for(int i = 1; i <= Q; i++)
        {
            int X, Y;
            cin >> X >> Y; // [25] 读入女性朋友的两个负数编号
            int a = abs(X); // [26] 负数编号取绝对值,适配数组下标
            int b = abs(Y);
            // [27] 调用女性并查集合并函数,跳转至该函数完成注释
            unite_female(a, b);
        }
        
        // [34] 回到主函数,女性关系处理完成
        int cnt_male = 0; // [35] 统计变量:和小明(编号1)连通的男性人数
        int root_male = find_male(1); // [36] 获取小明所在集合的根节点
        // [37] 遍历所有男性,统计和小明同集合的人数
        for(int i = 1; i <= N; i++)
        {
            if(find_male(i) == root_male)
            {
                cnt_male++;
            }
        }
        
        int cnt_female = 0; // [38] 统计变量:和小红(编号-1,绝对值1)连通的女性人数
        int root_female = find_female(1); // [39] 获取小红所在集合的根节点
        // [40] 遍历所有女性,统计和小红同集合的人数
        for(int i = 1; i <= M; i++)
        {
            if(find_female(i) == root_female)
            {
                cnt_female++;
            }
        }
        
        // [41] 最多舞伴对数为男性人数和女性人数的最小值(一男一女配对)
        cout << min(cnt_male, cnt_female) << endl;
        return 0; // [42] 主函数正常结束
    }
    
    // [14] 跳转至男性并查集find函数:带路径压缩,查找节点x的根节点
    int find_male(int x)
    {
        // [15] 函数参数x:待查找根节点的男性编号
        if(x != fa_male[x])
        {
            fa_male[x] = find_male(fa_male[x]); // [16] 路径压缩:直接将节点指向根节点
        }
        return fa_male[x]; // [17] 返回找到的根节点
    }
    // [18] find_male函数注释完成,返回unite_male函数继续注释
    
    // [19] 跳转至男性并查集unite函数:按秩合并x和y所在的两个集合
    void unite_male(int x, int y)
    {
        // [19] 函数参数x、y:待合并的两个男性编号
        x = find_male(x);
        y = find_male(y);
        
        if(x == y) return; // 两人已属于同一集合,无需重复合并
        
        // 按秩合并逻辑:将深度更小的树合并到深度更大的树下
        if(dep_male[x] > dep_male[y])
        {
            fa_male[y] = x;
        }
        else if(dep_male[x] < dep_male[y])
        {
            fa_male[x] = y;
        }
        else
        {
            fa_male[y] = x;
            dep_male[x]++;
        }
    }
    // [20] unite_male函数注释完成,返回主函数继续注释
    
    // [28] 跳转至女性并查集find函数:带路径压缩,查找节点x的根节点
    int find_female(int x)
    {
        // [29] 函数参数x:待查找根节点的女性编号(已取绝对值)
        if(x != fa_female[x])
        {
            fa_female[x] = find_female(fa_female[x]); // [30] 路径压缩:直接将节点指向根节点
        }
        return fa_female[x]; // [31] 返回找到的根节点
    }
    // [32] find_female函数注释完成,返回unite_female函数继续注释
    
    // [33] 跳转至女性并查集unite函数:按秩合并x和y所在的两个集合
    void unite_female(int x, int y)
    {
        // [33] 函数参数x、y:待合并的两个女性编号(已取绝对值)
        x = find_female(x);
        y = find_female(y);
        
        if(x == y) return; // 两人已属于同一集合,无需重复合并
        
        // 按秩合并逻辑:将深度更小的树合并到深度更大的树下
        if(dep_female[x] > dep_female[y])
        {
            fa_female[y] = x;
        }
        else if(dep_female[x] < dep_female[y])
        {
            fa_female[x] = y;
        }
        else
        {
            fa_female[y] = x;
            dep_female[x]++;
        }
    }
    // [34] unite_female函数注释完成,返回主函数继续注释
    

    信息

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