zoukankan      html  css  js  c++  java
  • 「SNOI2019」通信 分治建图

     根据题意 每个点可以直接与S,T相连 也可以和前面的哨站相连 暴力建边的话 有n2条边

    要用分治优化建边:

    类似于归并排序 先对每一层分为左半边与右半边 对每一半都拿出来先排序去重后 直接排成一条链建边

    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);
                    }
            }
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef long long JQK;
    const int inf = INT_MAX / 2;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() << "
    ";
            return 0;
    }
  • 相关阅读:
    C语言I作业12—学期总结
    C语言寒假大作战01
    C语言I作业12—学期总结
    C语言I博客作业11
    C语言I作业9
    C语言I博客作业08
    C语言I博客作业07
    C语言I博客作业05
    C语言I博客作业04
    C语言I博客作业03
  • 原文地址:https://www.cnblogs.com/Aragaki/p/11618485.html
Copyright © 2011-2022 走看看