AtCoder AGC034D Manhattan Max Matching (network flow)

Topic Link

https://atcoder.jp/contests/agc034/tasks/agc034_d

answer

Chi-thought out down to build a map ...... (DE but this is really upside down)
noted that the Manhattan distance has an important property: the legal maximum, that is, for any number of dimensions in terms of Manhattan distance of two points , we assume that the absolute value of each symbol arbitrarily changed to a plus or minus sign, then the legitimate (actual) Manhattan distance which is the biggest of all values. Obviously proof.
Well, since we are seeking the maximum distance and the coordinates of the two points can be ignored there is no legal problem of the four split the absolute wrong way connections are required.
FIG flow construction cost considerations, points are built in two rows show two balls, and then four more points representative of four kinds of matching mode, each point of each intermediate point and the corresponding sides of the even mode matching intermediate weight, seeking maximum cost maximum flow can be.
Time complexity \ (O (MFMC (n-, 10N)) \) , appears to the complexity of the cost flow algorithm may be estimated as \ (O (mC \ log m ) \) where \ (C \) is the maximum flow rate, and here the maximum flow rate is \ (O (S) \) , so the complexity of \ (O (nS \ log the n-) \) .
Interpretations says can simulate the cost flow do \ (O (S \ log the n-) \) . .. shivering

Code

#include<bits/stdc++.h>
#define llong long long
#define mkpr make_pair
#define riterator reverse_iterator
using namespace std;

inline int read()
{
    int x = 0,f = 1; char ch = getchar();
    for(;!isdigit(ch);ch=getchar()) {if(ch=='-') f = -1;}
    for(; isdigit(ch);ch=getchar()) {x = x*10+ch-48;}
    return x*f;
}

const llong INF = 1e12;

namespace NetFlow
{
    const int N = 2006;
    const int M = 10000;
    struct AEdge
    {
        int u,v,wl,wr; llong c;
    } ae[M+3];
    struct Edge
    {
        int u,v,nxt,w; llong c;
    } e[(M<<1)+3];
    int fe[N+3];
    llong dis[N+3];
    int que[N+5];
    bool inq[N+3];
    int lst[N+3];
    int n,m,en,s,t; llong mf,mc;
    void addedge(int u,int v,int w,llong c)
    {
//      printf("addedge %d %d %d %lld\n",u,v,w,c);
        en++; e[en].u = u,e[en].v = v,e[en].w = w,e[en].c = c;
        e[en].nxt = fe[u]; fe[u] = en;
        en++; e[en].u = v,e[en].v = u,e[en].w = 0,e[en].c = -c;
        e[en].nxt = fe[v]; fe[v] = en;
    }
    bool spfa()
    {
        for(int i=1; i<=n; i++) dis[i] = -INF;
        int hd = 1,tl = 2; que[1] = s; dis[1] = 0;
        while(hd!=tl)
        {
            int u = que[hd]; hd++; if(hd>n+1) hd-=n+1;
            for(int i=fe[u]; i; i=e[i].nxt)
            {
                int v = e[i].v;
                if(e[i].w>0&&dis[e[i].v]<dis[u]+e[i].c)
                {
                    dis[e[i].v] = dis[u]+e[i].c; lst[e[i].v] = i;
                    if(!inq[e[i].v])
                    {
                        inq[e[i].v] = true;
                        que[tl] = e[i].v; tl++; if(tl>n+1) tl-=n+1;
                    }
                }
            }
            inq[u] = false;
        }
        return dis[t]!=-INF;
    }
    void calcflow()
    {
        int flow = 1e5;
        for(int u=t; u!=s; u=e[lst[u]].u)
        {
            flow = min(flow,e[lst[u]].w);
        }
        for(int u=t; u!=s; u=e[lst[u]].u)
        {
            e[lst[u]].w -= flow; e[lst[u]^1].w += flow;
        }
        mf += flow; mc += 1ll*flow*dis[t];
    }
    llong mfmc(int _n,int _s,int _t)
    {
        n = _n,s = _s,t = _t; mf = 0,mc = 0ll;
        while(spfa()) {calcflow();} return mc;
    }
}
using NetFlow::addedge;

const int N = 1000;
struct Point
{
    int x,y,cnt;
} a[N+3],b[N+3];
int n;

int main()
{
    NetFlow::en = 1;
    scanf("%d",&n);
    for(int i=1; i<=n; i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].cnt);
    for(int i=1; i<=n; i++) scanf("%d%d%d",&b[i].x,&b[i].y,&b[i].cnt);
    for(int i=1; i<=n; i++)
    {
        addedge(1,i+6,a[i].cnt,0);
        addedge(i+6,3,a[i].cnt,-a[i].x-a[i].y);
        addedge(i+6,4,a[i].cnt,-a[i].x+a[i].y);
        addedge(i+6,5,a[i].cnt,a[i].x-a[i].y);
        addedge(i+6,6,a[i].cnt,a[i].x+a[i].y);
    }
    for(int i=1; i<=n; i++)
    {
        addedge(i+n+6,2,b[i].cnt,0);
        addedge(3,i+n+6,b[i].cnt,b[i].x+b[i].y);
        addedge(4,i+n+6,b[i].cnt,b[i].x-b[i].y);
        addedge(5,i+n+6,b[i].cnt,-b[i].x+b[i].y);
        addedge(6,i+n+6,b[i].cnt,-b[i].x-b[i].y);
    }
    llong ans = NetFlow::mfmc(n+n+6,1,2);
    printf("%lld\n",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/suncongbo/p/12296931.html