"SNOI2019" communications divide and conquer built map

 

 May be S, T, and may be connected to the front side of outposts built directly connected to violent meaning of the questions for each point, then there are n- 2 sides

Use divide and conquer by Optimized Edge:

Similar to merge sort first on each floor is divided into the left half and the right half of each half to sort out directly arranged in a side chain built after the de-emphasis

if (l == r) {
                return ;
        }
        int mid = (l + r) >> 1;
        solve(l, mid), solve(mid + 1, r);
        int cnt = 0;
        for (int i = l; i <= r; i++) {
                aa[++cnt] = a[i];
        }
        sort(aa + 1, aa + 1 + cnt);
        cnt = unique(aa + 1, aa + cnt + 1) - aa - 1;
        int now = MCMF::MAXP;
        for (int i = 1; i < cnt; i++) {
                MCMF::addedge(now + i, now + i + 1, inf, aa[i + 1] - aa[i]);
                MCMF::addedge(now + i + 1, now + i, inf, aa[i + 1] - aa[i]);
        }

Then for a rear half of the front half of the number within each interval into

        for (int i = l; i <= r; i++) {
                int aim = lower_bound(aa + 1, aa + cnt + 1, a[i]) - aa;
                if (i <= mid) {
                        MCMF::addedge(now + aim, i + n, 1, 0);
                } else {
                        MCMF::addedge(i, now + aim, 1, 0);
                }
        }

 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long long JQK;
const int inf = INT_MAX / 2;
namespace MCMF {
        const JQK INF = LLONG_MAX / 2;
        const int MAXN = 50500, MAXM = 130000;
        int Head[MAXN], cur[MAXN], to[MAXM << 1], nxt[MAXM << 1], f[MAXM << 1], ed = 1;
        int S, T, MAXP, MAXF, pre[MAXN];
        JQK lev[MAXN], cost[MAXM << 1];
        bool exist[MAXN];
        void addedge(int u, int v, int cap, JQK val) {
                //cout << u << " " << v << " " << cap << " " << val << endl;
                to[++ed] = v;
                nxt[ed] = Head[u];
                Head[u] = ed;
                f[ed] = cap;
                cost[ed] = val;++ ed] =
                to [ u;
                nxt[ed] = Head[v];
                Head[v] = ed;
                f[ed] = 0;
                cost[ed] = -1 * val;
                return;
        }
        bool spfa() {
                int u;
                queue<int>q;
                for (int i = 0; i <= MAXP + 1; i++) {
                        exist[i] = 0;
                        lev[i] = INF;
                }
                //memset(exist, false, sizeof(exist));
                //memset(lev, 127, sizeof(lev));
                lev[S] = pre[S] = 0;
                q.push(S);
                while (q.size()) {
                        u = q.front();
                        q.pop();
                        exist[u] = false;
                        for (int i = Head[u]; i; i = nxt[i])
                                if (f[i] && lev[u] + cost[i] < lev[to[i]]) {
                                        lev[to[i]] = lev[u] + cost[i];
                                        pre[to[i]] = i;
                                        if (!exist[to[i]]) {
                                                exist[to[i]] = true;
                                                q.push(to[i]);
                                        }
                                }
                }
                for (int i = 0; i <= MAXP + 1; i++) {
                        cur[i] = Head[i];
                }
                //memcpy(cur, Head, sizeof(Head));
                return lev[T] != INF;
        }
        JQK Augment() {
                JQK delta = 0x7f7f7f7f;
                for (int i = pre[T]; i; i = pre[to[i ^ 1]])
                        if (f[i] < delta) {
                                delta = f[i];
                        }
                for (int i = pre[T]; i; i = pre[to[i ^ 1]]) {
                        f[i] -= delta;
                        f[i ^ 1] += delta;
                }
                MAXF += delta;
                return delta * lev[T];
        }
        void init(int S1, int T1) {
                MAXF = 0;
                S = S1;
                T = T1;
                return;
        }
        JQK MCMF() {
                JQK ans = 0;
                memset(exist, false, sizeof(exist));
                while (spfa())
                        //ans+=DFS(S,INF)*lev[T];
                {
                        ans += Augment();
                }
                return ans;
        }
}
inline void RR(int &x) {
        char c;
        bool sign = false;
        for (c = getchar(); c < '0' || c > '9'; c = getchar())
                if (c == '-') {
                        sign = true;
                }
        for (x = 0; c >= '0' && c <= '9'; c = getchar()) {
                x = x * 10 + c - '0';
        }
        sign && (x = -x);
}
int n, a[1005], aa[1005];
void solve(int l, int r) {
        if (l == r) {
                return ;
        }
        int mid = (l + r) >> 1;
        solve(l, mid), solve(mid + 1, r);
        int cnt = 0;
        for (int i = l; i <= r; i++) {
                aa[++cnt] = a[i];
        }
        sort(aa + 1, aa + 1 + cnt);
        cnt = unique(aa + 1, aa + cnt + 1) - aa - 1;
        int now = MCMF::MAXP;
        for (int i = 1; i < cnt; i++) {
                MCMF::addedge(now + i, now + i + 1, inf, aa[i + 1] - aa[i]);
                MCMF::addedge(now + i + 1, now + i, inf, aa[i + 1] - aa[i]);
        }
        for (int i = l; i <= r; i++) {
                int aim = lower_bound(aa + 1, aa + cnt + 1, a[i]) - aa;
                if (i <= mid) {
                        MCMF::addedge(now + aim, i + n, 1, 0);
                } else {
                        MCMF::addedge(i, now + aim, 1, 0);
                }
        }
        MCMF::MAXP += cnt;
}
int main() {
        int x;
        int s, t;
        ll W;
        RR(n), RR(x);
        W = x;
        MCMF::MAXP = 2 * n + 3, s = 2 * n + 1, t = 2 * n + 2;
        for (int i = 1; i <= n; i++) {
                RR(a[i]);
                MCMF::addedge(s, i, 1, 0), MCMF::addedge(i, t, 1, W), MCMF::addedge(i + n, t, 1, 0);
        }
        solve(1, n);
        MCMF::init(s, t);
        cout << MCMF::MCMF() << "\n";
        return 0;
}

 

Guess you like

Origin www.cnblogs.com/Aragaki/p/11618485.html