真是一代不如一代了

P3376 【模板】网络最大流

ddwqwq @ 2017-12-24 13:51:33

最开始用EK,360多ms,改用一般预留推送变成800ms,现在改用更优的前置-重贴标签算法,三个RE70分

难道更快的算法不如EK皮实,经不起我糟蹋?

大家帮忙看看吧

#include <cstdlib>
#include <iostream>
#include <cstdio>
#include <math.h>
#include <cstring>

using namespace std;

struct node {
    int aim;
    int w;
    node *next;
};
struct Node {
    int v;
    Node *next;
    Node *last;
};

int S, T;
int N, M, X;
int c[250000], e[20005], h[20005], c_size;
node *head[20005], *cur[20005];

void add(node *&head, int aim, int w)
{
    node *p = new(node);
    p->next = NULL;
    p->aim = aim;
    p->w = c_size;
    c[c_size++] = w;
    if (head == NULL)
        head = p;
    else
    {
        p->next = head;
        head = p;
    }
}

int min(int a, int b)
{
    if (a < b)
        return a;
    return b;
}

void prepare(int s)
{
    h[s] = N;
    node *p = head[s];
    while (p != NULL)
    {
        if (c[p->w] > 0)
        {
            int w = c[p->w];
            e[p->aim] += w;
            c[p->w] = 0;
            c[p->w ^ 1] += w;
        }
        p = p->next;
    }
}

void push(int u, node *p)
{
    if (e[u] > 0 && c[p->w] > 0 && h[u] == h[p->aim] + 1)
    {
        int w = min(c[p->w], e[u]);
        c[p->w] -= w;
        c[p->w ^ 1] += w;
        e[u] -= w;
        e[p->aim] += w;
    }
}

void relable(int v)
{
    int i = 99999999;
    node *p = head[v];
    while (p != NULL)
    {
        if (c[p->w] > 0)
        {
            i = min(i, h[p->aim]);
        }
        p = p->next;
    }
    h[v] = i + 1;
}

void discharge(int v)
{
    while (e[v] > 0)
    {
        node *p = cur[v];
        if (p == NULL)
        {
            relable(v);
            cur[v] = head[v];
        }
        else if (c[p->w] > 0 && h[v] == h[p->aim] + 1)
            push(v, p);
        else
            cur[v] = p->next;
    }
}

void addNode(Node *&head, int v)
{
    Node *p = new(Node);
    p->v = v;
    p->next = NULL;
    p->last = NULL;
    if (head == NULL)
        head = p;
    else
    {
        p->next = head;
        head->last = p;
        head = p;
    }
}

void relable_to_front()
{
    prepare(S);
    Node *L = NULL;
    int i;
    for (i = 1; i <= N; i++)
        if (i != S&&i != T)
        {
            addNode(L, i);
            cur[i] = head[i];
        }

    Node *p = L;
    while (p != NULL)
    {
        int old_h = h[p->v];
        discharge(p->v);
        if (h[p->v] > old_h)
        {
            addNode(L, p->v);
            if (p->last != NULL)
                p->last->next = p->next;
            if (p->next != NULL)
                p->next->last = p->last;
            delete(p);
            p = L;
        }
        p = p->next;
    }
}

int main()
{
    //    freopen("C:/Users/david/Desktop/testdata.in", "r", stdin);
    //    freopen("C:/Users/david/Desktop/test.out", "w", stdout);
    int i, x, y, C;

    scanf("%d %d %d %d", &N, &M, &S, &T);

    for (i = 0; i < M; i++)
    {
        scanf("%d %d %d", &x, &y, &C);
        add(head[x], y, C);
        add(head[y], x, 0);
    }

    relable_to_front();

    printf("%d", e[T]);

//    system("pause");
    return 0;
}

by SeKong @ 2017-12-24 14:04:05

并不是,我EK,DINIC,ISAP跑的都比你快,ISAP只要20ms,EK和Dinic也只是100ms左右


by _rqy @ 2017-12-24 15:14:28

嗯,Dinic和ISAP时间复杂度都很松qwq...

但是前置重贴标签的时间复杂度是紧的


|