首页 > 其他 > 详细

[ICPC2020南京D] Degree of Spanning Tree - 树

时间:2021-03-27 18:49:21      阅读:30      评论:0      收藏:0      [点我收藏+]

[ICPC2020南京D] Degree of Spanning Tree - 树

Description

给定无向图,如果有解,构造最大度不超过 \(n/2\) 的生成树。

Solution

任意找一棵生成树然后调整,对于度数大于 n/2 的点做调整,枚举与 p 关联的非树边,加入后删除环上一条边,如果这样导致了另一个点度数爆炸那么这两个点显然相邻,去掉这条边再换入一条新边即可

事实上可以随机 DFS 生成 100 个生成树

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

#define int long long

const int N = 1e5 + 5;
int n, m, deg[N];
vector<pair<int, int>> ans;
vector<int> g[N];
int vis[N], tot;

void dfs(int p)
{
    vis[p] = 1;
    ++tot;
    random_shuffle(g[p].begin(), g[p].end());
    for (int q : g[p])
    {
        if (deg[p] >= n / 2)
            break;
        if (vis[q] == 0)
        {
            ans.push_back({p, q});
            deg[p]++;
            deg[q]++;
            dfs(q);
        }
    }
}

bool fuck()
{
    for (int i = 1; i <= n; i++)
        deg[i] = 0,
        vis[i] = 0;
    tot = 0;
    dfs(rand() * rand() % n + 1);
    if (tot == n)
        return true;
    return false;
}

void solve()
{
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
    {
        g[i].clear();
    }
    ans.clear();
    for (int i = 1; i <= m; i++)
    {
        int u, v;
        cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }

    for (int i = 1; i <= 99; i++)
    {
        if (fuck())
        {
            cout << "Yes" << endl;
            for (auto [x, y] : ans)
                cout << x << " " << y << endl;
            return;
        }
        else
        {
            ans.clear();
        }
    }
    cout << "No" << endl;
}

signed main()
{
    srand(time(0));
    ios::sync_with_stdio(false);
    int t;
    cin >> t;
    while (t--)
        solve();
}

[ICPC2020南京D] Degree of Spanning Tree - 树

原文:https://www.cnblogs.com/mollnn/p/14586171.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!