洛谷 最小费用最大流 模板 P3381

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define N 200100
#define INF 100000000
using namespace std;
int ecnt=1,vis[N],dist[N],n,m,S,T,ans,head[N];
deque <int> q;
struct adj
{
    int nxt,v,w,c;
}e[N];
inline void add(int u,int v,int w,int c)
{
    e[++ecnt].v=v,e[ecnt].w=w,e[ecnt].c=c,e[ecnt].nxt=head[u],head[u]=ecnt;
    e[++ecnt].v=u,e[ecnt].w=0,e[ecnt].c=-c,e[ecnt].nxt=head[v],head[v]=ecnt;
}
inline int spfa(int s,int t)
{
    int v;
    memset(vis,0,sizeof(vis));
    for (int i=s;i<=t;i++) dist[i]=INF;
    dist[t]=0,vis[t]=1;
    q.push_back(t);
    while (!q.empty())
    {
	int u=q.front();q.pop_front();
	for (int i=head[u];i;i=e[i].nxt)
	    if (e[i^1].w>0 && dist[v=e[i].v]>dist[u]-e[i].c)
	    {
		dist[v]=dist[u]-e[i].c;
		if (!vis[v])
		{
		    vis[v]=1;
		    if (!q.empty() && dist[v]<dist[q.front()])
			q.push_front(v);
		    else
			q.push_back(v);
		}
	    }
	vis[u]=0;
    }
    return dist[s]<INF;
}
inline int dfs(int x,int flow)
{
    if (x==T)
	return vis[T]=1,flow;
    int used=0,tmp,v;
    vis[x]=1;
    for (int i=head[x];i;i=e[i].nxt)
	if (!vis[v=e[i].v] && e[i].w>0 && dist[x]-e[i].c==dist[v])
	{
	    tmp=dfs(v,min(e[i].w,flow-used));
	    if (tmp>0)
		ans+=tmp*e[i].c,e[i].w-=tmp,e[i^1].w+=tmp,used+=tmp;
	    if (used==flow) break;
	}
    return used;
}
inline int CostFlow()
{
    int Flow=0;
    while (spfa(S,T))
    {
	vis[T]=1;
	while (vis[T])
	{
	    memset(vis,0,sizeof(vis));
	    Flow+=dfs(S,INF);
	}
    }
    return Flow;
}
int main()
{
    scanf("%d%d%d%d",&n,&m,&S,&T);
    for (int i=1,u,v,w,c;i<=m;i++)
    {
	scanf("%d%d%d%d",&u,&v,&w,&c);
	add(u,v,w,c);
    }
    printf("%d ",CostFlow());
    printf("%d",ans);
    return 0;
}

 

posted @ 2017-12-01 20:20  MSPqwq  阅读(138)  评论(0编辑  收藏  举报