[CF1037E] Trips - set,时间倒流
Description
有 (n) 个人,他们开始互不认识,而每天早上恰好有原来不认识的两个人变成朋友。一共有 (m) 天,每天晚上有的人要去旅行,去旅行的人必须满足有至少 (k)(固定值)个朋友也去旅行。求每天去旅行的最大人数。
Solution
先把所有边都连上,然后考虑倒着删边
如果一个点的度小于 k,我们就将其自动删除
删边可能引发删点,删点也可能引发删点
怎样保证不会重复删除(删点的时候已经删掉了,删边的时候又删?)全部用 set 维护,不手动记录 size,这样重复删除就没有影响了
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 200005;
int n, m, k, x[N], y[N], ans[N];
set<int> g[N], s;
signed main()
{
ios::sync_with_stdio(false);
cin >> n >> m >> k;
for (int i = 1; i <= m; i++)
{
cin >> x[i] >> y[i];
g[x[i]].insert(y[i]);
g[y[i]].insert(x[i]);
}
for (int i = 1; i <= n; i++)
{
s.insert(i);
}
function<void(int)> check = [&](int p) -> void {
if (g[p].size() < k && s.find(p) != s.end())
{
s.erase(p);
for (int q : g[p])
{
g[q].erase(p);
check(q);
}
}
};
for (int i = 1; i <= n; i++)
check(i);
for (int i = m; i >= 1; i--)
{
ans[i] = s.size();
g[x[i]].erase(y[i]);
g[y[i]].erase(x[i]);
check(x[i]);
check(y[i]);
}
for (int i = 1; i <= m; i++)
cout << ans[i] << endl;
}