费用流

#include<bits/stdc++.h>
using namespace std;
char buf[1<<20],*_=buf,*__=buf;
#define gc() (_==__&&(__=(_=buf)+fread(buf,1,1<<20,stdin),_==__)?EOF:*_++)
#define TT template<class T>inline
TT bool read(T &x){
    x=0;char c=gc();bool f=0;
    while(c<48||c>57){if(c==EOF)return 0;f^=(c=='-'),c=gc();}
    while(47<c&&c<58)x=(x<<3)+(x<<1)+(c^48),c=gc();
    if(f)x=-x;return 1;
}
TT bool read(T&a,T&b){return read(a)&&read(b);}
TT bool read(T&a,T&b,T&c){return read(a)&&read(b)&&read(c);}
typedef long long ll;
const ll MAXN=5008,mod=1e9+7,inf=0x3f3f3f3f;
struct Mcfm{
    struct E{int y,nt;ll flow,cost;}e[MAXN*20];
    int head[MAXN],cnt=1;
    void add(int x,int y,ll flow,ll cost){//x->y
        e[++cnt].y=y;
        e[cnt].flow=flow;
        e[cnt].cost=cost;
        e[cnt].nt=head[x];head[x]=cnt;
    }
    int n,m,s,t;
    int dis[MAXN],now[MAXN];
    bool vis[MAXN];
    deque<int>que;
    bool spfa(){
        for(int i=0;i<=n;++i)dis[i]=inf,now[i]=head[i];
        que.emplace_back(s),dis[s]=0,vis[s]=1;
        int x,y;
        while(!que.empty()){
            x=que.front(),que.pop_front();
            vis[x]=0;
            for(int i=head[x];i;i=e[i].nt){
                y=e[i].y;
                if(e[i].flow>0&&dis[y]>dis[x]+e[i].cost){
                    dis[y]=dis[x]+e[i].cost;
                    if(!vis[y]){
                        if(!que.empty()&&dis[y]<dis[que.front()])
                        	que.emplace_front(y);
                        else que.emplace_back(y);
                        vis[y]=1;
                    }
                }
            }
        }
        return dis[t]!=inf;
    }
    ll mincost=0,maxflow=0;
    ll dfs(int x,ll totflow){
        if(x==t||totflow==0)return totflow;
        vis[x]=1;
        ll ansflow=0,flow;
        for(int&i=now[x],y;i;i=e[i].nt){
            y=e[i].y;
            if(vis[y]||e[i].flow<=0||dis[x]+e[i].cost!=dis[y])continue;
            flow=dfs(e[i].y,min(totflow,e[i].flow));
            if(flow<=0)dis[y]=-1;
            e[i].flow-=flow;
            e[i^1].flow+=flow;
            totflow-=flow;
            ansflow+=flow;
            mincost+=flow*e[i].cost;
            if(!totflow)break;
        }return vis[x]=0,ansflow;
    }
    void dinic(){
        ll flow;
        while(spfa())
            while((flow=dfs(s,1ll<<50))>0)
        maxflow+=flow;
    }
}mcfm;
int main() {
    read(mcfm.n,mcfm.m);read(mcfm.s,mcfm.t);
    int x,y;ll f,c;
    for(int i=0;i<mcfm.m;++i){
        read(x,y);read(f,c);
        mcfm.add(x,y,f,c);
        mcfm.add(y,x,0,-c);
    }
    mcfm.dinic();
    cout<<mcfm.maxflow<<" "<<mcfm.mincost<<endl;
    return 0;
}
//dijkstra版,需要o2优化不然慢
struct Mcfm{
    struct E{int y,nt;ll flow,cost;}e[MAXN];
    int head[MAXN],cnt=1;
    void add(int x,int y,ll flow,ll cost){//x->y
        e[++cnt].y=y;
        e[cnt].flow=flow;
        e[cnt].cost=cost;
        e[cnt].nt=head[x];head[x]=cnt;
    }
    int n,m,s,t;
    ll dis[MAXN],h[MAXN];
    bool vis[MAXN];
    void spfa(){
        for(int i=0;i<=n;++i)h[i]=inf;
        queue<int>que;
        que.emplace(s),h[s]=0,vis[s]=1;
        int x,y;
        while(!que.empty()){
            x=que.front(),que.pop();
            vis[x]=0;
            for(int i=head[x];i;i=e[i].nt){
                y=e[i].y;
                if(e[i].flow>0&&h[y]>h[x]+e[i].cost){
                    h[y]=h[x]+e[i].cost;
                    if(!vis[y])que.emplace(y),vis[y]=1;
                }
            }
        }
    }
    ll mincost,maxflow;
    int prep[MAXN],pree[MAXN];
    typedef pair<ll,int>pii;
    priority_queue<pair<ll,int>>que;
    void mcfm(){
        mincost=maxflow=0;
        spfa();
        while(1){
            for(int i=0;i<=n;++i)dis[i]=inf;
            pree[s]=0,prep[s]=0,dis[s]=0;
            while(!que.empty())que.pop();
            que.emplace(0,s);
            while(!que.empty()){
                pii tmp=que.top();que.pop();
                int x=tmp.second;
                if(-tmp.first!=dis[x])continue;
                for(int i=head[tmp.second],y;i;i=e[i].nt){
                    y=e[i].y;
                    ll len=e[i].cost+h[x]-h[y];
                    if(e[i].flow>0&&dis[y]>dis[x]+len){
                        dis[y]=dis[x]+len;
                        que.emplace(-dis[y],y);
                        pree[y]=i,prep[y]=x;
                    }
                }
            }
            if(dis[t]==inf)break;
            ll flow=inf;
            for(int i=t;i^s;i=prep[i])flow=min(flow,e[pree[i]].flow);
            for(int i=t;i^s;i=prep[i]){
                e[pree[i]].flow-=flow;
                e[pree[i]^1].flow+=flow;
            }
            maxflow+=flow;
            mincost+=flow*(dis[t]+h[t]);
            for(int i=0;i<=n;++i)h[i]=min(h[i]+dis[i],inf);
        }
    }
}mcfm;
posted @ 2020-12-19 22:59  肆之月  阅读(98)  评论(0编辑  收藏  举报