[CF1483A] Basic Diplomacy - 构造
Description
有 (n) 个朋友和 (m) 天假期,每天他会选一个朋友和他一起玩团队游戏。而每天只有特定的朋友能和他玩。如果一个朋友被选了 (leftlceildfrac{m}{2} ight ceil) 次,别的朋友就会吃醋。问是否存在一种方案使得没有朋友吃醋。
Solution
扫两轮,同时记录每个人的使用次数
第一轮只定下所有只能选一个人的天
第二轮定剩下的,每次随便找一个还有剩余使用次数的人
如果无解,那么一定是在第一轮中超标,第二轮中不可能导致超标,因为不可能有两个人同时超标的情况出现
#include <bits/stdc++.h>
using namespace std;
#define int long long
void solve()
{
int n, m;
cin >> n >> m;
vector<vector<int>> g(m + 2);
for (int i = 1; i <= m; i++)
{
int siz;
cin >> siz;
for (int j = 0; j < siz; j++)
{
int x;
cin >> x;
g[i].push_back(x);
}
}
vector<int> seq(m + 2), cnt(n + 2);
for (int i = 1; i <= m; i++)
{
if (g[i].size() == 1)
{
seq[i] = g[i][0];
cnt[seq[i]]++;
if (cnt[seq[i]] > (m + 1) / 2)
{
cout << "NO" << endl;
return;
}
}
}
for (int i = 1; i <= m; i++)
{
if (seq[i])
continue;
int now = 0;
for (int j = 0; j < g[i].size(); j++)
{
now = g[i][j];
if (cnt[now] >= (m + 1) / 2)
continue;
break;
}
seq[i] = now;
cnt[now]++;
}
cout << "YES" << endl;
for (int i = 1; i <= m; i++)
cout << seq[i] << " ";
cout << endl;
}
signed main()
{
int t;
cin >> t;
while (t--)
{
solve();
}
}