[Cf1186F] F. Vus the Cossack and a Graph (dfs tree randomization +)

Portal

The meaning of problems:
Given an (n-\) \ dots \ (m \) free edges of the directed graph is defined \ (D_i \) for the first \ (I \) points degrees.
To now remove some edges, so that the last retention \ (\ displaystyle \ lceil \ frac {n + m} {2} \ rceil \) edges.
Defined \ (F_i \) is the final point on the graph degrees, then to satisfy the \ (. 1 \ Leq I \ n-Leq \) , are \ (\ displaystyle \ lceil \ frac {d_i} {2} \ rceil \ leq f_i \) .
The last output reserved side.

Ideas:

  • If \ (m \ n-Leq \) , apparently can directly retain all sides;
  • If \ (m> n-\) , we found only need to remove all of the rings to meet the condition. We certainly noticed a ring can be removed so that the degree of an edge to meet the conditions, it is possible to remove all of the ring.
  • So by \ (dfs \) construct \ (dfs \) tree can go directly to the ring.
  • Only once \ (dfs \) if possible because of the degree of limitation can not remove all the rings, then we only need to go to the starting point of several randomly selected to ring.

As proof of correctness is not good at, but it feels should be able to remove all the rings to meet the conditions of the degree of restriction.
If you have a big brother to know if want to let me know.
code show as below:

/*
 * Author:  heyuhhh
 * Created Time:  2020/3/19 20:57:08
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#include <random>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '\n'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
  template <template<typename...> class T, typename t, typename... A> 
  void err(const T <t> &arg, const A&... args) {
  for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
  #define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e6 + 5;

int n, m;

struct Edge {
    int u, v;
} edges[N];

vector <pii> G[N];
vector <int> res;
bool chk[N], out[N];
int d[N], f[N];

void dfs(int u, int fa) {
    chk[u] = true;
    for(auto it : G[u]) if(it.fi != fa) {
        int v = it.fi, i = it.se;
        if(out[i]) continue;
        if(chk[v]) {
            if(f[u] - 1 >= (d[u] + 1) / 2 && f[v] - 1 >= (d[v] + 1) / 2) {
                out[i] = true;
                --f[u], --f[v];
            }
            continue;
        }
        dfs(v, u);
    }   
}

mt19937 rnd(time(NULL));

void run() {
    cin >> n >> m;
    for(int i = 1; i <= m; i++) {
        int u, v; cin >> u >> v;
        G[u].push_back(MP(v, i));
        G[v].push_back(MP(u, i));
        edges[i] = Edge {u, v};
        ++d[u], ++d[v];
    }
    for(int i = 1; i <= n; i++) f[i] = d[i];
    if(m <= n) {
        cout << m << '\n';
        for(int i = 1; i <= m; i++) {
            cout << edges[i].u << ' ' << edges[i].v << '\n';   
        }
    } else {
        for(int i = 1; i <= 20; i++) {
            memset(chk, false, sizeof(chk));
            int rt = rnd() % n + 1;
            dfs(rt, 0);   
        }
        for(int i = 1; i <= m; i++) if(!out[i]) res.push_back(i);
        cout << sz(res) << '\n';
        for(auto it : res) {
            cout << edges[it].u << ' ' << edges[it].v << '\n';   
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    run();
    return 0;
}

Guess you like

Origin www.cnblogs.com/heyuhhh/p/12548626.html