[CF1037E] Trips

[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;
}
原文地址:https://www.cnblogs.com/mollnn/p/14387915.html