ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[ SDOI2016 ] 数字配对

2021-06-12 13:33:33  阅读:206  来源: 互联网

标签:pre 数字 idx int flow add cost SDOI2016 配对


题目

Luogu
LOJ
Acwing

思路

001.png

代码

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define int long long
const int N = 410, M = 200010, INF = 1e18;
int n, m, S, T, A[N], B[N], C[N];
int h[N], val[M], ptr[M], f[M], w[M], idx;
void add(int a, int b, int c, int d) { val[idx] = b, f[idx] = c, w[idx] = d, ptr[idx] = h[a], h[a] = idx++; }
void add(int a, int b, int c, int d, int e) { add(a, b, c, e), add(b, a, d, -e); }
bool check(int x, int y) {
    if (x < y) swap(x, y);
    if (x % y != 0 || x == y) return false;
    int t = x / y;
    for (int i = 2; i <= t / i; i++)
        if (t % i == 0) return false;
    return true;
}
int q[N], d[N], pre[M], incf[N], st[N];
// 最大费用最大流
bool SPFA() {
    int hh = 0, tt = 0;
    memset(d, -0x3f, sizeof d), memset(incf, 0, sizeof incf);
    q[tt++] = S, incf[S] = INF, d[S] = 0, st[S] = true;
    while (hh != tt) {
        int t = q[hh++];
        if (hh == N - 1) hh = 0;
        st[t] = false;
        for (int i = h[t], v = val[i]; i != -1; i = ptr[i], v = val[i]) {
            if (f[i] && d[v] < d[t] + w[i]) {
                d[v] = d[t] + w[i], pre[v] = i;
                incf[v] = min(incf[t], f[i]);
                if (st[v]) continue;
                q[tt++] = v, st[v] = true;
                if (tt == N - 1) tt = 0;
            }
        }
    } 
    return incf[T] > 0;
}
int EK() {
    int flow = 0, cost = 0;
    while (SPFA()) {
        int t = incf[T];
        if (cost + d[T] * t < 0) {
            flow += (cost / (-d[T]));
            return flow;
        } else cost += d[T] * t, flow += t;
        for (int i = T; i != S; i = val[pre[i] ^ 1]) 
            f[pre[i]] -= t, f[pre[i] ^ 1] += t;
    }
    return flow;
}
signed main() {
    cin >> n;
    memset(h, -1, sizeof h);
    S = 2 * n + 1, T = n * 2 + 2;
    for (int i = 1; i <= n; i++) cin >> A[i];
    for (int i = 1; i <= n; i++) cin >> B[i];
    for (int i = 1; i <= n; i++) cin >> C[i];
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            if (check(A[i], A[j])) 
                add(i, j + n, INF, 0, C[i] * C[j]);
    
    for (int i = 1; i <= n; i++) add(S, i, B[i], 0, 0);
    for (int i = 1; i <= n; i++) add(n + i, T, B[i], 0, 0);

    cout << EK() / 2 << endl;
    return 0;
}

标签:pre,数字,idx,int,flow,add,cost,SDOI2016,配对
来源: https://www.cnblogs.com/Proteinlzl/p/14878095.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有