1 条题解
-
0
📝 题目大意
有 个人和 场派对,每场派对给出参加者的编号。判断是否任意两个人都至少共同参加过同一场派对,即所有人两两之间是否至少共处过一次。
💡 解题思路
-
题目分析:,数据规模很小,可以直接暴力处理。问题本质上是要验证一个无向完全图是否可以被所有派对所覆盖——每场派对将其中参加者两两连边,最终检查是否所有 条边都存在。
-
算法推导:
- 用一个 的布尔矩阵
pair来记录每对人是否共同参加过派对(pair[i][j]表示编号为 和 的两个人是否同场过)。 - 遍历每场派对,对于该场派对中的 个参加者,枚举所有 对人,将
pair矩阵中对应位置标记为true。 - 处理完所有派对后,遍历所有 ,检查
pair[i][j]是否全为true。若存在false,输出"No";否则输出"Yes"。
- 用一个 的布尔矩阵
-
边界与细节:
- 输入中人的编号是 到 ,代码中将其减 转为 到 ,方便数组索引。
- 每场派对人数 ,保证至少有两人,枚举对时不会出现空循环。
- 只检查上三角 即可,避免重复判断。
⏱️ 复杂度分析
- 时间复杂度:。每场派对至多 人,枚举 对人, 场派对最坏 ;最后检查 。由于 , 级别运算量完全可行。
- 空间复杂度:,用于存储布尔矩阵。
💻 标准代码 (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
- 上传者