题意:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210424015812373.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDE3ODczNg==,size_16,color_FFFFFF,t_70)
解法:
如果某一天只有一个数,那么显然这个数必被选.
设出现最多的数为x,如果由多个出现次数相同,那么任选一个.
如果x必被选的次数超过了(m+1)/2次,那么一定无解.
否则有两种情况:
1.x的出现次数不超过(m+1)/2,
由于x已经是出现次数最多的了,那么剩下的数随便选都不可能超过(m+1)/2.
2.x的出现次数超过了(m+1)/2,
那么先选其中(m+1)/2个x,之后其他数随便选都不可能超过(m+1)/2了.
code:
#include<bits/stdc++.h>
using namespace std;
const int maxm=2e6+5;
vector<int>g[maxm];
int ans[maxm];
int cnt[maxm];
int n,m;
void solve(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cnt[i]=0;
g[i].clear();
}
for(int i=1;i<=m;i++){
ans[i]=0;
}
for(int i=1;i<=m;i++){
int k;cin>>k;
for(int j=1;j<=k;j++){
int x;cin>>x;
if(k==1){
cnt[x]++;
ans[i]=x;
}
g[x].push_back(i);
}
}
int ma=1;
for(int i=1;i<=n;i++){
if(g[i].size()>g[ma].size()){
ma=i;
}
}
int num=cnt[ma];
if(num>(m+1)/2){
cout<<"NO"<<endl;
return ;
}
for(auto i:g[ma]){
if(num==(m+1)/2)break;
if(!ans[i]){
ans[i]=ma;
num++;
}
}
for(int i=1;i<=n;i++){
if(i==ma)continue;
for(auto j:g[i]){
if(!ans[j]){
ans[j]=i;
}
}
}
cout<<"YES"<<endl;
for(int i=1;i<=m;i++){
cout<<ans[i]<<' ';
}
cout<<endl;
}
signed main(){
ios::sync_with_stdio(0);
int T;cin>>T;
while(T--){
solve();
}
return 0;
}