题解:P11811 [PA 2015] 人赢 / Mistrzostwa

为了解决这个问题,我们需要找到一个最大的连通点集,使得每个点的度数至少为 d,并且该点集的导出子图是连通的。我们可以通过以下步骤来实现:

方法思路

  1. 预处理阶段:首先计算每个节点的度数,并将度数小于d的节点进行拓扑排序式的删除。这些节点及其边会被逐步移除,直到所有剩余节点的度数都不小于 d。

  2. 连通分量查找:在剩余的节点中,使用 BFS 查找最大的连通分量。这个连通分量即为满足条件的最大点集。

代码

#include <bits/stdc++.h>
using namespace std;

const int N = 2e5 + 5;

vector<int> edge[N];
int l[N], in[N], vis[N];
    
int main() {
    ios :: sync_with_stdio(false);
    cin.tie(0);

    int n, m, d;
    cin >> n >> m >> d;
    for (int i = 0; i < m; ++i) {
        int u, v;
        cin >> u >> v;
        edge[u].push_back(v);
        edge[v].push_back(u);
        in[u]++;
        in[v]++;
    }

    queue<int> q;
    for (int u = 1; u <= n; ++u) {
        if (in[u] < d) {
            vis[u] = true;
            q.push(u);
        }
    }

    while (!q.empty()) {
        int u = q.front();
        q.pop();
        for (int v : edge[u]) {
            if (!vis[v]) {
                in[v]--;
                if (in[v] < d) {
                    vis[v] = true;
                    q.push(v);
                }
            }
        }
    }
    memset(vis, 0, sizeof(vis));
    for (int u = 1; u <= n; ++u) {
        if (!vis[u] && !visited[u]) {
            vector<int> c;
            queue<int> Q;
            Q.push(u);
            visited[u] = true;
            c.push_back(u);
            while (!Q.empty()) {
                int curr = Q.front();
                Q.pop();
                for (int v : edge[curr]) {
                    if (!vis[v] && !visited[v]) {
                        visited[v] = true;
                        c.push_back(v);
                        Q.push(v);
                    }
                }
            }
            if (c.size() > l.size()) {
                l = c;
            }
        }
    }

    if (l.empty()) {
        cout << "NIE\n";
    }
	else {
        sort(l.begin(), l.end());
        cout << l.size() << '\n';
        for (size_t i = 0; i < l.size(); ++i) {
            cout << l[i] << (i + 1 < l.size() ? " " : "");
        }
        cout << '\n';
    }

    return 0;
}
posted @ 2025-09-16 19:45  yanbinmu  阅读(5)  评论(0)    收藏  举报