1 条题解

  • 0
    @ 2026-6-19 10:30:17

    📝 题目大意

    NN 个人和 MM 场派对,每场派对给出参加者的编号。判断是否任意两个人都至少共同参加过同一场派对,即所有人两两之间是否至少共处过一次。

    💡 解题思路

    1. 题目分析N,M100N, M \le 100,数据规模很小,可以直接暴力处理。问题本质上是要验证一个无向完全图是否可以被所有派对所覆盖——每场派对将其中参加者两两连边,最终检查是否所有 (N2)\binom{N}{2} 条边都存在。

    2. 算法推导

      • 用一个 N×NN \times N 的布尔矩阵 pair 来记录每对人是否共同参加过派对(pair[i][j] 表示编号为 iijj 的两个人是否同场过)。
      • 遍历每场派对,对于该场派对中的 kk 个参加者,枚举所有 (k2)\binom{k}{2} 对人,将 pair 矩阵中对应位置标记为 true
      • 处理完所有派对后,遍历所有 i<ji < j,检查 pair[i][j] 是否全为 true。若存在 false,输出 "No";否则输出 "Yes"
    3. 边界与细节

      • 输入中人的编号是 11NN,代码中将其减 11 转为 00N1N-1,方便数组索引。
      • 每场派对人数 ki2k_i \ge 2,保证至少有两人,枚举对时不会出现空循环。
      • 只检查上三角 (i<j)(i < j) 即可,避免重复判断。

    ⏱️ 复杂度分析

    • 时间复杂度O(Mkmax2+N2)O(M \cdot k_{\max}^2 + N^2)。每场派对至多 NN 人,枚举 (N2)\binom{N}{2} 对人,MM 场派对最坏 O(MN2)O(MN^2);最后检查 O(N2)O(N^2)。由于 N,M100N, M \le 10010610^6 级别运算量完全可行。
    • 空间复杂度O(N2)O(N^2),用于存储布尔矩阵。

    💻 标准代码 (C++)

    #include<bits/stdc++.h>
    using namespace std;
    int main(){
        int N, M;
        cin >> N >> M;
        // pair[i][j] 表示第 i 个人和第 j 个人是否共同参加过派对
        vector<vector<bool>> pair(N, vector<bool> (N, false));
        for(int i = 0; i < M; i++){
            int k;  cin >> k;
            vector<int> ball(k);
            // 读入参加者编号,转为 0-indexed
            for(auto &x: ball) cin >> x, x--;
            // 枚举该场派对中所有两人组合,标记为共同参加过
            for(int j = 0; j < k - 1; j++)
                for(int l = j + 1; l < k; l++)
                    pair[ball[j]][ball[l]] = true;
        }
        // 检查所有 (i, j) 对,i < j
        for(int i = 0; i < N - 1; i++)
            for(int j = i + 1; j < N; j++)
                if(pair[i][j] == false){  // 存在未共同参加过派对的人
                    cout << "No" << endl;
                    return 0;
                }
        cout << "Yes" << endl;
    }
    
    • 1

    信息

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