专栏文章

题解:P11954 「ZHQOI R1」删边

P11954题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miptojp1
此快照首次捕获于
2025/12/03 17:46
3 个月前
此快照最后确认于
2025/12/03 17:46
3 个月前
查看原文

分析

题目要求看起来很容易满足。
所以考虑直接求这个图的生成树,把生成树上的边删除,再删去一条两端没有叶子的边。
注意到无法删去边时生成树是菊花。此时只需将任意一条在生成树上(小心重边)的边放到生成树上,并将相邻的任意一条在生成树上的边删去即可。

Code

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

int u[500005], v[500005], vis[500005], fa[500005], d[500005];
set<pair<int, int> > p;

int find_fa(int x) {
    return fa[x] ? (fa[x] = find_fa(fa[x])) : x;
}

void output(int m) {
    int cnt = 0;
    for (int i = 1; i <= m; i ++) {
        if (!vis[i]) cnt ++;
    }
    cout << cnt << '\n';
    for (int i = 1; i <= m; i ++) {
        if (!vis[i]) cout << u[i] << ' ' << v[i] << '\n';
    }
    exit(0);
}

int main() {
    ios::sync_with_stdio(false);
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= m; i ++) {
        cin >> u[i] >> v[i];
    }
    for (int i = 1; i <= m; i ++) {
        if (find_fa(u[i]) != find_fa(v[i])) {
            fa[find_fa(u[i])] = find_fa(v[i]);
            vis[i] = true;
            d[u[i]] ++;
            d[v[i]] ++;
        }
    }
    for (int i = 1; i <= m; i ++) {
        if (vis[i] && d[u[i]] > 1 && d[v[i]] > 1) {
            vis[i] = false;
            output(m);
        }
    }
    for (int i = 1; i <= m; i ++) {
        if (!vis[i] && !p.count(make_pair(min(u[i], v[i]), max(u[i], v[i])))) {
            for (int j = 1; j <= m; j ++) {
                if (vis[j] && (u[i] == u[j] || u[i] == v[j] || v[i] == u[j] || v[i] == v[j])) {
                    vis[j] = false;
                    vis[i] = true;
                    d[u[i]] ++;
                    d[v[i]] ++;
                    d[u[j]] --;
                    d[v[j]] --;
                    for (int i = 1; i <= m; i ++) {
                        if (vis[i] && d[u[i]] > 1 && d[v[i]] > 1) {
                            vis[i] = false;
                            output(m);
                        }
                    }
                    cout << "-1\n";
                    return 0;
                }
            }
            assert(false);
        }
        p.insert(make_pair(min(u[i], v[i]), max(u[i], v[i])));
    }
    cout << "-1\n";
    return 0;
}
updated on 2025/4/21\texttt{updated on 2025/4/21}

评论

0 条评论,欢迎与作者交流。

正在加载评论...