【板子】费用流(Zkw)

世界上最好的费用流板子!

//lg p3381
#include<bits/stdc++.h>
using namespace std;

#define ll long long
const int N= (int)5e3+3;
const int M =(int)5e4+4;
const ll INF = (0x3f3f3f3f3f3f3f3f);

int n,m,st,ed;
ll maxflow,ans;

bool vis[N],inq[N];
int cur[N];
ll dis[N];

int edgeid=1;
int head[N];
struct edge
{
    int v,nxt;
    ll cost,w;
}e[M*2];
void addedge(int u,int v,ll w,ll cost)
{
    edgeid++;
    e[edgeid].v=v;
    e[edgeid].w=w;
    e[edgeid].cost=cost;
    e[edgeid].nxt=head[u];
    head[u]=edgeid;

    edgeid++;
    e[edgeid].v=u;
    e[edgeid].w=0;
    e[edgeid].cost=-cost;
    e[edgeid].nxt=head[v];
    head[v]=edgeid;
}

deque<int> q;
bool Spfa()
{
    for(int i=1;i<=n;i++) dis[i]=0x3f3f3f3f3f3f3f3f,inq[i]=0;
    q.push_front(ed);
    dis[ed]=0;
    inq[ed]=1;
    while(!q.empty())
    {
        int u=q.front();
        q.pop_front();
        inq[u]=0;
        for(int i=head[u];i;i=e[i].nxt)
        {
            int v=e[i].v;
            if(dis[v]>dis[u]-e[i].cost && e[i^1].w)
            {
                dis[v]=dis[u]-e[i].cost;
                if(!inq[v])
                {
                    if(!q.empty() && dis[v]<dis[q.front()]) q.push_front(v);
                    else q.push_back(v);
                    inq[v]=1;
                }
            }
        }
    }
    return (dis[st]<0x3f3f3f3f3f3f3f3f);
}

ll Dfs(int u,ll rst)
{
    vis[u]=1;
    if(u==ed || !rst) return rst;
    ll sum=0;
    for(int i=cur[u];i;i=e[i].nxt)
    {
        cur[u]=i;
        int v=e[i].v;
        ll f;
        if(dis[v]==dis[u]-e[i].cost && e[i].w && !vis[v]  
        &&(f=Dfs(v,min(rst,e[i].w))))
        {
            sum+=f;
            rst-=f;
            e[i].w-=f;
            e[i^1].w+=f;
            if(!rst) break;
        }
    }
    return sum;
}

void Zkw()
{
    while(Spfa())
    {
        do
        {
            for(int i=1;i<=n;i++) vis[i]=0,cur[i]=head[i];
            ll tmp=Dfs(st,INF);
            maxflow+=tmp;
            ans+=tmp*dis[st];
        }while(vis[ed]);
    }
}

int main()
{
    cin>>n>>m>>st>>ed;
    for(int i=1;i<=m;i++)
    {
        int u,v;
        ll cost,w;
        scanf("%d%d%lld%lld",&u,&v,&w,&cost);
        addedge(u,v,w,cost);
    }
    Zkw();
    cout<<maxflow<<" "<<ans;
    return 0;
}
posted @ 2024-02-05 23:13  yeyou26  阅读(28)  评论(0编辑  收藏  举报