1 条题解

  • 1
    @ 2025-1-15 16:40:57
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define RN 20000
    
    typedef int I;
    typedef char C;
    typedef long long L;
    
    #define SWAP(T, a, b) { T t = a; a = b; b = t; }
    
    #define getchar() (_S==_T&&(_T=(_S=_B)+fread(_B,1,1<<15,stdin),_S==_T)?EOF:*_S++)
    char _B[1 << 15], *_S = _B, *_T = _B;
    inline int read() 
    {
        register int s = 0;
        register char ch;
    
        while ((ch = getchar()) < '0' || ch > '9');
    
        for (; ch >= '0' && ch <= '9'; s = ch - '0' + s * 10, ch = getchar());
    
        return s;
    }
    typedef struct 
    {
        I nxt;
        I to;
        I cap;
        I cost;
    }
    Network;
    
    Network net_pool[RN * 2];
    I ncnt = 1;
    
    #define nnode(x) net_pool[x]
    #define nnxt(x)  nnode(x).nxt
    #define nto(x)   nnode(x).to
    #define ncap(x)  nnode(x).cap
    #define ncost(x) nnode(x).cost
    
    
    I head[RN], fa[RN], fe[RN], pi[RN], mark[RN], buf[RN];
    I ti, nc;
    
    static inline void addEdge(I u, I v, I f, I c) 
    {
        nnode(++ncnt) = (Network) 
        {
            head[u], v, f, c
        };
        head[u] = ncnt;
        nnode(++ncnt) = (Network) 
        {
            head[v], u, 0, -c
        };
        head[v] = ncnt;
    }
    
    void initTree(I x) 
    {
        nc++, mark[x] = 1;
    
        for (I i = head[x]; i; i = nnxt(i)) 
        {
            I v = nto(i);
    
            if (!mark[v] && ncap(i)) 
            {
                fa[v] = x, fe[v] = i;
                initTree(v);
            }
        }
    }
    
    static inline I phi(I x) 
    {
        I top = 0;
    
        while (mark[x] != ti)
            mark[buf[top++] = x] = ti, x = fa[x];
    
        while (top--)
            x = buf[top], pi[x] = pi[fa[x]] - ncost(fe[x]);
    
        return pi[x];
    }
    
    void pushFlow(I e, L *cost) 
    {
        I u = nto(e ^ 1), v = nto(e), l = nc, r = nc;
        ti++;
    
        while (u)
            buf[++r] = fe[u], mark[u] = ti, u = fa[u];
    
        while (mark[v] != ti)
            buf[--l] = fe[v] ^ 1, mark[v] = ti, v = fa[v];
    
        buf[nc] = e;
    
        I e2 = l;
    
        for (I i = l; buf[i] != fe[v]; ++ i) 
        {
            if (ncap(buf[e2]) > ncap(buf[i]))
                e2 = i;
        }
    
        I f = ncap(buf[e2]);
    
        for (I i = l; buf[i] != fe[v]; ++ i) 
        {
            ncap(buf[i]) -= f, ncap(buf[i] ^ 1) += f;
            *cost += 1ll * ncost(buf[i]) * f;
        }
    
        if (e2 == nc)
            return;
    
        I x = e ^ (e2 < nc), y = nto(x), z = nto(x ^ 1);
    
        while (x != (buf[e2] ^ (e2 < nc))) 
        {
            x ^= 1;
            pi[z] = pi[y] - ncost(x);
            SWAP(I, x, fe[z]);
            SWAP(I, y, fa[z]);
            SWAP(I, y, z);
        }
    }
    
    I simplex(I st, I ed, L *cost) 
    {
        I lhead = head[st], lhead2 = head[ed];
        addEdge(ed, st, 0x3f3f3f3f, -0x3f3f3f3f);
        nc = fa[ed] = *cost = 0;
        initTree(ed);
        mark[ed] = ti = 2;
    
        for (I i = 2, pre = ncnt; i != pre; i = i == ncnt ? 2 : i + 1) 
        {
            if (ncap(i) && ncost(i) < phi(nto(i ^ 1)) - phi(nto(i)))
                pushFlow(pre = i, cost);
        }
    
        head[st] = lhead, head[ed] = lhead2, ncnt -= 2;
        return ncap(ncnt + 2);
    }
    
    int main() 
    {
        I n, m, s, t;
        n = read();
        m = read();
        s = 1, t = n;
    
        for (register I i = 1; i <= m; ++ i) 
        {
            I u, v, f, c;
            u = read();
            v = read();
            f = read();
            c = read();
            addEdge(u, v, f, c);
        }
    
        L cost;
        I flow = simplex(s, t, &cost);
        printf("%d %lld\n", flow, cost + 1ll * flow * 0x3f3f3f3f);
        return 0;
    }
    
    • 1

    信息

    ID
    5533
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者