P8252 [NOI Online 2022 提高组] 讨论题解
题意
有 n 个人,有 n 道题,每个人有一个自己会的题的集合,求是否存在任意两个人他们的集合相交且互不包含。
分析
我才不会说这是KH神教我的
我们从无解的情况开始考虑,那么任意两个人之间要么没有交集,要么包含,所以我们可以设计这样的算法:贪心地想,按集合从大到小找,建一个树形结构(感性理解吧,想象一下),结点是题的编号。首先把最大的那一坨染成他的编号,然后再依次插入每个人,在遍历的过程中我们记录出现的颜色,记录之后顺便把他染成当前的编号,如果在遍历过程中出现了两种不同的颜色,证明我们找到了合法解,输出即可。
#include<cstdio> #include<queue> #include<iostream> #include<cstring> #include<algorithm> #include<cmath> #include<cctype> #include<vector> #include<string> using namespace std; const int N = 1e6 + 5; int id[N],k[N],col[N],n,t; vector<int>v[N]; inline bool cmp(int x,int y){ return k[x] > k[y]; } int main(){ //freopen("discuss2.in","r",stdin); scanf("%d",&t); while(t--){ memset(k,0,sizeof(k)); memset(col,0,sizeof(col)); memset(id,0,sizeof(id)); scanf("%d",&n); for(int i=1;i<=n;++i){ scanf("%d",k+i); id[i] = i; v[i].clear(); for(int x,j=1;j<=k[i];++j){ scanf("%d",&x); v[i].push_back(x); } } sort(id+1,id+1+n,cmp);//按集合大小降序 for(int x : v[id[1]])col[x] = id[1];//最大的一坨染色 int cnt = 1; k[0] = 1e9; for(int i=2;i<=n;++i){ cnt++; int flag = 0,color = 0; for(int x : v[id[i]]){ if(color != col[x] && flag){//第二种颜色 printf("YES\n%d %d\n",id[i],k[col[x]] < k[color] ? col[x] : color);//避免颜色为0 goto QWQ; } if(flag == 0)flag = 1;//第一种颜色 color = col[x];//记录颜色 col[x] = id[i];//染色 } } puts("NO"); QWQ:; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构