LOJ 101 最大流(ISAP 模板)

开long long的最大流

#include<bits/stdc++.h>
using namespace std;
const long long MAXN = 4000010;//点数的最大值
const long long MAXM = 4000010;//边数的最大值
const long long INF = 1e15 + 7;
struct Edge
{
    long long to,next,cap,flow;
} edge[MAXM]; //注意是MAXM
long long tol;
long long head[MAXN];
long long gap[MAXN],dep[MAXN],cur[MAXN];
long long n, m, s, t;
void init()
{
    tol = 0;
    memset(head,-1,sizeof(head));
}
void addedge(long long u,long long v,long long w,long long rw = 0)
{
    edge[tol].to = v;
    edge[tol].cap = w;
    edge[tol].flow = 0;
    edge[tol].next = head[u];
    head[u] = tol++;
    edge[tol].to = u;
    edge[tol].cap = rw;
    edge[tol].flow = 0;
    edge[tol].next = head[v];
    head[v] = tol++;
}
long long Q[MAXN];
void BFS(long long start,long long end)
{
    memset(dep,-1,sizeof(dep));
    memset(gap,0,sizeof(gap));
    gap[0] = 1;
    long long front = 0, rear = 0;
    dep[end] = 0;
    Q[rear++] = end;
    while(front != rear)
    {
        long long u = Q[front++];
        for(long long i = head[u]; i != -1; i = edge[i].next)
        {
            long long v = edge[i].to;
            if(dep[v] != -1)
                continue;
            Q[rear++] = v;
            dep[v] = dep[u] + 1;
            gap[dep[v]]++;
        }
    }
}
long long S[MAXN];
long long sap(long long start,long long end,long long N)
{
    BFS(start,end);
    memcpy(cur,head,sizeof(head));
    long long top = 0;
    long long u = start;
    long long ans = 0;
    while(dep[start] < N)
    {
        if(u == end)
        {
            long long Min = INF;
            long long inser;

            for(long long i = 0; i < top; i++)
                if(Min > edge[S[i]].cap - edge[S[i]].flow)
                {
                    Min = edge[S[i]].cap - edge[S[i]].flow;
                    inser = i;
                }
            for(long long i = 0; i < top; i++)
            {
                edge[S[i]].flow += Min;
                edge[S[i]^1].flow -= Min;
            }
            ans += Min;
            top = inser;
            u = edge[S[top]^1].to;
            continue;
        }
        bool flag = false;
        long long v;
        for(long long i = cur[u]; i != -1; i = edge[i].next)
        {
            v = edge[i].to;
            if(edge[i].cap - edge[i].flow && dep[v]+1 == dep[u])
            {
                flag = true;
                cur[u] = i;
                break;
            }
        }
        if(flag)
        {
            S[top++] = cur[u];
            u = v;
            continue;
        }
        long long Min = N;
        for(long long i = head[u]; i != -1; i = edge[i].next)
            if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min)
            {
                Min = dep[edge[i].to];
                cur[u] = i;
            }
        gap[dep[u]]--;
        if(!gap[dep[u]])
            return ans;
        dep[u] = Min + 1;
        gap[dep[u]]++;
        if(u != start)
            u = edge[S[--top]^1].to;
    }
    return ans;
}
int main(){
    init();
    scanf("%lld %lld %lld %lld", &n , &m, &s, &t);
    for(long long i = 0; i < m; i++){
        long long u, v, w;
        scanf("%lld %lld %lld", &u, &v, &w);
        addedge(u,v,w);
    }
    printf("%lld\n", sap(s,t,n));
}

猜你喜欢

转载自www.cnblogs.com/Jadon97/p/9696474.html