HLPP模板 qaq

HLPP模板

// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#define MAXN 13000
#define N 250000
using namespace std;
const int inf=(1<<29);
inline char nc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void read(int &x)
{
    int s=0,w=1;
    char c=nc();
    while(!isdigit(c)){if(c=='-')w=-1;c=nc();}
    while(isdigit(c)){s=(s<<3)+(s<<1)+c-'0';c=nc();}
    x=s*w;
}
inline void write(int x)
{
    if(x<0)x=-x,putchar('-');
    if(x>9)write(x/10);
    putchar(x%10+'0');
}
template <class T,int max_size,bool compare(const T &a,const T &b)>class Heap
{
private:
  T heap[max_size];
  int heap_size;
  inline void swap(T &a,T &b)
  {
    T temp=a;
    a=b,b=temp;
  }
  void up(int now)
  {
    if(now==1)return ;
    int nxxt=now>>1;
    T temp=heap[now];
    while(compare(temp,heap[nxxt])&&now>1)
    {
        heap[now]=heap[nxxt];
        now=nxxt,nxxt>>=1;
    }
    heap[now]=temp;
  }
  void down(int now)
  {
    int nxxt=now<<1;
    T temp=heap[now];
    while(nxxt<=heap_size)
    {
        if(nxxt<heap_size&&compare(heap[nxxt+1],heap[nxxt]))
        nxxt++;
        if(compare(temp,heap[nxxt]))break;
        else
        {
            heap[now]=heap[nxxt];
            now=nxxt,nxxt<<=1;
        }
    }
    heap[now]=temp;
  }
public:
  Heap()
  {
    heap_size=0;
  }
  inline void push(T a)
  {
      heap[++heap_size]=a;
      up(heap_size);
  }
  inline void pop()
  {
    heap[1]=heap[heap_size--];
    down(1);
  }
  inline T top(){return heap[1];}
  inline T pop_out()
  {
    T temp=heap[1];
    heap[1]=heap[heap_size--];
    down(1);
    return temp;
  }
  inline void clear(){heap_size=0;}
  inline bool empty(){return !heap_size;}
  inline int size(){return heap_size;}
};
struct edge
{
    int to,nxxt,flow;
}e[N];
struct data
{
    int pos,h;
    data(int x=0,int y=0){pos=x,h=y;}
}t[MAXN];
inline bool cmp(const data &a,const data &b)
{
    return a.h>b.h;
}
int head[MAXN],cnt=-1,n,H[MAXN],F[MAXN],Gap[MAXN],m,ss,tt;
inline void add(int x,int y,int w)
{
    e[++cnt].to=y;
    e[cnt].nxxt=head[x];
    e[cnt].flow=w;
    head[x]=cnt;
}
Heap<data,MAXN,cmp>Q;
inline int HLPP(int S,int T)
{
    H[S]=n,F[S]=inf;
    Q.push(data(S,H[S]));
    while(!Q.empty())
    {
        int now=Q.top().pos;
        Q.pop();
        if(!F[now])continue;
        register int i;
        for(i=head[now];~i;i=e[i].nxxt)
        {
            if(now==S||H[e[i].to]+1==H[now])
            {
                int flow=min(F[now],e[i].flow);
                e[i].flow-=flow,e[i^1].flow+=flow;
                F[now]-=flow,F[e[i].to]+=flow;
                if(e[i].to^T&&e[i].to^S&&flow)
                Q.push(data(e[i].to,H[e[i].to]));
            }
        }
        if(now^S&&now^T&&F[now])
        {
            if(!(--Gap[H[now]]))
            {
                for(i=1;i<=n;i++)
                if(H[now]<H[i]&&H[i]<=n&&now^S&&now^T)H[i]=n+1;
            }
            ++Gap[++H[now]];
            Q.push(data(now,H[now]));
        }
    }
    return F[T];
}
int main()
{
    memset(head,-1,sizeof(head));
    read(n),read(m),read(ss),read(tt);
    for(register int i=1;i<=m;i++)
    {
        int u,v,w;
        read(u),read(v),read(w);
        add(u,v,w),add(v,u,0);
    }
    write(HLPP(ss,tt)),putchar(10);
}

一种不基于增广路的高效(?)最大流算法,由Tarjan和???于1986年提出,并证明复杂度上界为 O ( n 2 m )

猜你喜欢

转载自blog.csdn.net/assass_cannotin/article/details/79623128