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;
    }
  • 相关阅读:
    MySQL管理工具-SQLyog 9.63的使用详解
    通讯录管理系统
    Mavenx学习找对方法,快速上手!
    晚风花间寺中人
    PE重装系统,U盘重装系统,一步到位,重装无忧!
    进入博客园的第一篇随笔,贡献给我最喜欢的作家-大冰
    天地有情尽白发,人间无意了沧桑
    狼和羊的故事(安徒生新篇)
    .Net Core CLR GC的浅度分析
    .net core 的夸代扫描标记card_table的细节分析
  • 原文地址:https://www.cnblogs.com/Aragaki/p/11618485.html
Copyright © 2011-2022 走看看