【题解】Atcoder ARC#85 E-MUL

  ……没啥可说的。最大权闭合子图,跑下dinic就好了……

#include <bits/stdc++.h>
using namespace std;
#define maxn 500000
#define int long long
#define INF 99999999999LL
int n, sum, S, T, lev[maxn];

int read()
{
    int x = 0, k = 1;
    char c; c = getchar();
    while(c < '0' || c > '9') { if(c == '-') k = -1; c = getchar(); }
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * k;
}

struct edge
{
    int cnp, to[maxn], f[maxn], last[maxn], head[maxn], cur[maxn];
    edge() { cnp = 2; }
    void add(int u, int v, int fl)
    {
        to[cnp] = v, f[cnp] = fl, last[cnp] = head[u], head[u] = cnp ++;
        to[cnp] = u, f[cnp] = 0, last[cnp] = head[v], head[v] = cnp ++;
    }
}E1;

bool bfs()
{
    memset(lev, 0, sizeof(lev));
    queue <int> q; q.push(S); lev[S] = 1;
    while(!q.empty())
    {
        int u = q.front(); q.pop();
        for(int i = E1.head[u]; i; i = E1.last[i])
        {
            int v = E1.to[i];
            if(!lev[v] && E1.f[i])
            { lev[v] = lev[u] + 1; q.push(v); }
        }
        if(lev[T]) return 1;
    }
    return 0;
}

int dfs(int u, int nf)
{
    if(u == T) return nf;
    int tf = 0;
    for(int i = E1.cur[u]; i; i = E1.last[i])
    {
        int v = E1.to[i];
        if(lev[v] == lev[u] + 1 && E1.f[i])
        {
            int af = dfs(v, min(nf, E1.f[i]));
            tf += af, nf -= af;
            E1.f[i] -= af, E1.f[i ^ 1] += af;
            if(!nf) return tf;
            E1.cur[u] = i;
        }
    }
    return tf;
}

int Dinic()
{
    int ret = 0;
    while(bfs())
    {
        memcpy(E1.cur, E1.head, sizeof(E1.head));
        ret += dfs(S, INF);
    }
    return ret;
}

signed main()
{
    n = read(); S = 0, T = n + 3;
    for(int i = 1; i <= n; i ++) 
    {
        int x = read();
        if(x > 0) sum += x, E1.add(i, T, x); 
        else if(x <= 0) E1.add(S, i, -x);
    }
    for(int i = 1; i <= n; i ++)
        for(int j = 2; i * j <= n; j ++)
            if(i * j <= n) E1.add(i, i * j, INF);
    printf("%lld\n", sum - Dinic());
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/twilight-sx/p/9760343.html