【网络流】最小费用最大流(模板)

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

const int Max=50010;
const int inf=1e9;
int n,m,ans1,ans2,size=1,head,tail,s,t;
int first[Max],dis[Max],p[Max],exist[Max],vis[Max],temp[Max];
struct shu{int to,next,len,val;};
shu bian[Max*2];

inline int get_int()
{
   int x=0,f=1;
   char c;
   for(c=getchar();(!isdigit(c))&&(c!='-');c=getchar());
   if(c=='-') {f=-1;c=getchar();}
   for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
   return x*f;
}

inline void build(int x,int y,int z,int w)
{
   bian[++size].next=first[x];first[x]=size;bian[size].to=y;bian[size].len=z;bian[size].val=w;
}

inline int spfa()
{
   for(int i=1;i<=tail;i++) p[i]=0;
   for(int i=1;i<=n;i++) {dis[i]=inf;exist[i]=0;}
   head=0,tail=1;dis[s]=0;p[1]=s;
   while(head<=tail)
   {
     int point=p[++head];
     exist[point]=0;
     for(int u=first[point];u;u=bian[u].next)
     {
       if(bian[u].len > 0 && dis[point]+bian[u].val < dis[bian[u].to])
       {
       	 dis[bian[u].to]=dis[point]+bian[u].val;
       	 //pre[bian[u].to]=u;
       	 if(!exist[bian[u].to])
       	 {
       	   exist[bian[u].to]=1;
       	   p[++tail]=bian[u].to;
       	 }
       }
     }
   }
   if(dis[t] == inf) return 0;
   else return 1;
}

inline int dfs(int point,int flow)
{
   if(point == t) return flow;
   vis[point]=1;
   int sum=0;
   for(int &u=temp[point];u;u=bian[u].next)
   	 if(!vis[bian[u].to] && dis[bian[u].to] == dis[point] + bian[u].val && bian[u].len > 0)
   	 {
   	   int minn=dfs(bian[u].to,min(flow-sum,bian[u].len));
       ans2+=minn*bian[u].val;
   	   bian[u].len-=minn;
   	   bian[u^1].len+=minn;
   	   sum+=minn;
       if(flow-sum == 0) break;
     }
   vis[point]=0;
   return sum;
}

int main()
{
   freopen("lx.in","r",stdin);
   n=get_int();
   m=get_int();
   s=1;t=n;
   for(int i=1;i<=m;i++)
   {
   	 int x=get_int(),y=get_int(),z=get_int(),w=get_int();
   	 build(x,y,z,w);
   	 build(y,x,0,-w);
   }
   while(spfa())
   {
     memcpy(temp,first,sizeof(first));
     int x=dfs(s,inf);
     while(x)ans1+=x,x=dfs(s,inf);
   }

   cout<<ans1<<" "<<ans2<<"\n";
   return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_38083668/article/details/80342927