constructive algorithms flows graph matchings graphs implementation *2500

Please click on ads to support us..

C++ Code:

///Enta etfsh5t nseet el rank

#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("avx,avx2,fma")

#include "bits/stdc++.h"
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update

using namespace std;
using namespace __gnu_pbds;

template<typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,
        tree_order_statistics_node_update>;
#define pb push_back
#define F first
#define S second
#define f(i, a, b) for (int i = a; i < b; i++)
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define sz(x) (int)(x).size()
//#define mp(x, y) make_pair(x, y)
#define popCnt(x) (__builtin_popcountll(x))
#define int ll

using ll = long long;
using ull = unsigned long long;
using uint = uint32_t;
using ii = pair<int, int>;

const int N = 1e5 + 6, LG = 18, MOD = 1e9 + 7;
const long double PI = acos(-1);

const long double EPS = 1e-9;


int a[N], s[N];
int u[N], v[N];
int deg[N];
int n, m;

struct FlowEdge {
    int v, u;
    long long cap, flow = 0;

    FlowEdge(int v, int u, long long cap) : v(v), u(u), cap(cap) {}
};

struct Dinic {
    const long long flow_inf = 1e18;
    vector<FlowEdge> edges;
    vector<vector<int>> adj;
    int n, m = 0;
    int s, t;
    vector<int> level, ptr;
    queue<int> q;

    Dinic(int n, int s, int t) : n(n), s(s), t(t) {
        adj.resize(n);
        level.resize(n);
        ptr.resize(n);
    }

    void add_edge(int v, int u, long long cap) {
        edges.emplace_back(v, u, cap);
        edges.emplace_back(u, v, 0);
        adj[v].push_back(m);
        adj[u].push_back(m + 1);
        m += 2;
    }

    bool bfs() {
        while (!q.empty()) {
            int v = q.front();
            q.pop();
            for (int id: adj[v]) {
                if (edges[id].cap - edges[id].flow < 1)
                    continue;
                if (level[edges[id].u] != -1)
                    continue;
                level[edges[id].u] = level[v] + 1;
                q.push(edges[id].u);
            }
        }
        return level[t] != -1;
    }

    long long dfs(int v, long long pushed) {
        if (pushed == 0)
            return 0;
        if (v == t)
            return pushed;
        for (int &cid = ptr[v]; cid < (int) adj[v].size(); cid++) {
            int id = adj[v][cid];
            int u = edges[id].u;
            if (level[v] + 1 != level[u] || edges[id].cap - edges[id].flow < 1)
                continue;
            long long tr = dfs(u, min(pushed, edges[id].cap - edges[id].flow));
            if (tr == 0)
                continue;
            edges[id].flow += tr;
            edges[id ^ 1].flow -= tr;
            return tr;
        }
        return 0;
    }

    long long flow() {
        long long f = 0;
        while (true) {
            fill(level.begin(), level.end(), -1);
            level[s] = 0;
            q.push(s);
            if (!bfs())
                break;
            fill(ptr.begin(), ptr.end(), 0);
            while (long long pushed = dfs(s, flow_inf)) {
                f += pushed;
            }
        }
        return f;
    }
};

void doWork() {

    cin >> n >> m;
    Dinic flw(n + m + 5, 0, n + m + 1);
    f(i, 1, n + 1) cin >> s[i];
    f(i, 1, n + 1) cin >> a[i];
    f(i, 1, m + 1) {
        cin >> u[i] >> v[i];
        deg[u[i]] -= 1;
        deg[v[i]] -= 1;
        flw.add_edge(0, i, 1);
        flw.add_edge(i, m + u[i], 1);
        flw.add_edge(i, m + v[i], 1);
    }

    int totFlow = 0;
    f(i, 1, n + 1)if (s[i] == 1) {
            if ((a[i] - deg[i]) & 1) {
                cout << "NO\n";
                return;
            }
            if (a[i] < deg[i]) {
                cout << "NO\n";
                return;
            }
            flw.add_edge(m + i, n + m + 1, (a[i] - deg[i]) / 2);
            totFlow += (a[i] - deg[i]) / 2;
        }

    if (flw.flow() != totFlow) {
        cout << "NO\n";
        return;
    }
    f(i, 1, n + 1)if (!s[i])flw.add_edge(m + i, n + m + 1, 1e9);
    if (totFlow + flw.flow() != m) {
        cout << "NO\n";
        return;
    }
    cout << "YES\n";
    f(i, 1, m + 1) {
        int go;
        for (auto e: flw.adj[i])
            if (flw.edges[e].cap == flw.edges[e].flow && flw.edges[e].u != 0) {
                go = flw.edges[e].u - m;
                break;
            }
        if (u[i] == go)
            swap(u[i], v[i]);
        cout << u[i] << ' ' << v[i] << '\n';
    }


}

int32_t main() {
#ifdef ONLINE_JUDGE
    ios_base::sync_with_stdio(0);
    cin.tie(0);
#endif // ONLINE_JUDGE

    int t = 1;
//    cin >> t;
    while (t--)
        doWork();
    return 0;
}


Comments

Submit
0 Comments
More Questions

701. Insert into a Binary Search Tree
429. N-ary Tree Level Order Traversal
739. Daily Temperatures
647. Palindromic Substrings
583. Delete Operation for Two Strings
518. Coin Change 2
516. Longest Palindromic Subsequence
468. Validate IP Address
450. Delete Node in a BST
445. Add Two Numbers II
442. Find All Duplicates in an Array
437. Path Sum III
436. Find Right Interval
435. Non-overlapping Intervals
406. Queue Reconstruction by Height
380. Insert Delete GetRandom O(1)
332. Reconstruct Itinerary
368. Largest Divisible Subset
377. Combination Sum IV
322. Coin Change
307. Range Sum Query - Mutable
287. Find the Duplicate Number
279. Perfect Squares
275. H-Index II
274. H-Index
260. Single Number III
240. Search a 2D Matrix II
238. Product of Array Except Self
229. Majority Element II
222. Count Complete Tree Nodes