刚学OI1ms的萌新再次求助

P3376 【模板】网络最大流

Chiyoda_Momo @ 2019-08-02 09:40:08

闲的蛋疼写了个Link-Cut-Tree优化Dinic
复杂度O(nmlogn)怎么跑的比普通Dinic还慢啊……
是我复杂度实现错了还是它就是常数大的不行啊qwq
求助各位dalao
提交记录
预流推进T飞了


#include<cstdio>
#include<cctype>
#include<algorithm>
#include<queue>
#include<cstring>
#define mi(x) (x?x->min:inf)
const int inf=0x7fffffff;
const int N=20000;
const int M=200000;
struct edge{
    int nxt,to,val,del;
};
struct tree{
    bool rev;
    tree *son[2],*fa,*ref;
    int min,tag,val,id,nowd;
};
tree pl[N],*node[N];
edge t[M<<1];
int cnt_edge=-1,n,m,S,T,maxflow,fis[N],cur[N],dep[N];
inline void add_edge(const int&st,const int&ed,const int&vl){
    t[++cnt_edge].nxt=fis[st],t[cnt_edge].to=ed,t[cnt_edge].val=vl,fis[st]=cnt_edge;
}
inline void read(int &x){
    register char ch=0;
    for(;!std::isdigit(ch);ch=getchar());
    for(x=0;std::isdigit(ch);x=x*10+ch-'0',ch=getchar());
}
inline void pushup(tree *x){
    x->min=x->val,x->ref=x;
    if(mi(x->son[0])<x->min)x->min=x->son[0]->min,x->ref=x->son[0]->ref;
    if(mi(x->son[1])<x->min)x->min=x->son[1]->min,x->ref=x->son[1]->ref;
}
inline bool isroot(tree *x){
    return (!x->fa)||(x->fa->son[0]!=x&&x->fa->son[1]!=x);
}
inline int getdr(tree *x){
    return x->fa->son[1]==x;
}
inline void pushdown(tree *x){
    if(!x)return;
    if(x->tag){
        if(x->son[0])
            x->son[0]->min+=x->tag,x->son[0]->val+=x->tag,x->son[0]->tag+=x->tag,
            t[x->son[0]->id].val+=x->tag,t[x->son[0]->id^1].val-=x->tag;
        if(x->son[1])
            x->son[1]->min+=x->tag,x->son[1]->val+=x->tag,x->son[1]->tag+=x->tag,
            t[x->son[1]->id].val+=x->tag,t[x->son[1]->id^1].val-=x->tag;
        x->tag=0;
    }
    if(x->rev){
        if(x->son[0])x->son[0]->rev^=1;
        if(x->son[1])x->son[1]->rev^=1;
        std::swap(x->son[0],x->son[1]);
        x->rev=0;
    }
}
inline void rotate(tree *&x){
    tree *f=x->fa,*g=f->fa;int dr=getdr(x);
    if(!isroot(f))g->son[getdr(f)]=x;
    x->fa=g,f->son[dr]=x->son[dr^1],(f->son[dr])&&(f->son[dr]->fa=f),
    x->son[dr^1]=f,f->fa=x,pushup(f),pushup(x);
}
void update(tree *x){
    if(!isroot(x))update(x->fa);
    pushdown(x);
}
inline void splay(tree *x){
    update(x);
    for(tree *f;!isroot(x);rotate(x)){
        f=x->fa;if(!isroot(f))rotate(getdr(f)==getdr(x)?f:x);
    }
}
inline void access(tree *x){
    for(tree *now=NULL;x;now=x,x=x->fa)splay(x),x->son[1]=now,pushup(x);
}
inline void makeroot(tree *x){
    access(x),splay(x),x->rev^=1;
}
inline void split(tree *x,tree *y){
    makeroot(x),access(y),splay(y);
}
inline tree* find(tree *x){
    access(x),splay(x);
    while(x->son[0])pushdown(x),x=x->son[0];
    return x;
}
inline void cut(tree *x,tree *y){
    split(x,y),x->fa=NULL,y->son[0]=NULL;
}
inline void link(tree *x,tree *y){
    splay(x),x->fa=y;
}
void cutlson(tree *x){
    access(x),splay(x),x->son[0]->fa=NULL,x->son[0]=NULL,pushup(x);
}
inline void delete_(tree *x){
    pushdown(x);
    while(x->son[1]&&x->son[1]->min<=0)
        x=x->son[1]->ref,splay(x),x->son[0]->fa=NULL,x->son[0]=NULL,pushup(x);
}
bool bfs(){
    std::queue<int>que;
    memset(dep,0,sizeof(dep));
    for(register int i=1;i<=n;++i)cur[i]=fis[i];
    que.push(S),dep[S]=1;
    while(!que.empty()){
        int u=que.front();que.pop();
        for(register int i=fis[u];~i;i=t[i].nxt){
            int v=t[i].to;t[i].del=0;
            if(dep[v]||t[i].val<=0)continue;
            dep[v]=dep[u]+1,que.push(v);
        }
    }
    return dep[T]?1:0;
}
int dfs(tree *now){
    int nown=now->nowd;
    if(nown==T){
        access(node[S]),splay(node[T]);
        int flow=node[T]->min;
        maxflow+=flow,node[T]->tag-=flow,delete_(node[T]);
        return 1;
    }
    for(register int &i=cur[nown];~i;i=t[i].nxt){
        int v=t[i].to;
        if(dep[v]==dep[nown]+1&&!t[i].del&&t[i].val>0){
            link(now,node[v]),now->val=t[i].val,now->id=i,pushup(now);
            if(dfs(find(now)))return 1;
        }
    }
    for(register int i=fis[nown];~i;i=t[i].nxt){
        register int v=t[i].to;
        if(dep[v]==dep[nown]-1){
            if(find(node[v])==now)cutlson(node[v]);
            t[i^1].del=1;
        }
    }
    return 0;
}
int main(){
    memset(fis,-1,sizeof(fis));
    read(n),read(m),read(S),read(T);
    for(register int i=1;i<=m;++i){
        int s_,e_,v_;read(s_),read(e_),read(v_),
        add_edge(s_,e_,v_),add_edge(e_,s_,0);
    }
    for(register int i=1;i<=n;++i)node[i]=&pl[i],node[i]->val=inf,node[i]->nowd=i;
    while(bfs()){
        while(dfs(find(node[S])));
        for(register int i=1;i<=n;++i){
            node[i]->id=node[i]->tag=0,node[i]->son[0]=node[i]->son[1]=node[i]->fa=NULL,
            node[i]->val=inf,node[i]->rev=0;
        }
    }
 …

by 流逝丶 @ 2019-08-02 09:51:29

刚学oi就学最大流,%%%%%


by 良月澪二 @ 2019-08-02 09:52:06

网络流的复杂度就是能过和不能过哪需要什么优化


by Frozencode @ 2019-08-02 10:02:41

@Seniorious 闲的蛋疼就自己慢慢查 Orz 萌新


by Chiyoda_Momo @ 2019-08-02 10:04:24

@Frozencode 不是正确性的问题啊……qaq


by xyf007 @ 2019-08-02 10:22:54

@Seniorious 刚学oi就学最大流,%%%%%


by zhy137036 @ 2019-08-02 11:22:19

刚学OI一毫秒就学最大流,我学了一年还没学到。惭愧


|