int n,m; int frm[N],nxt[M],to[M],cap[M],cost[M],flow[M],_=1; int dis[N],pre[N],vis[N]; int S,T,V; void add_edge(int u,int v,int w,int c){ nxt[++_]=frm[u];frm[u]=_;to[_]=v;cap[_]=w;cost[_]=c; nxt[++_]=frm[v];frm[v]=_;to[_]=u;cap[_]=0;cost[_]=-c; } bool spfa(){ queue<int> Q; fill(dis,dis+V+1,INF); memset(vis,0,sizeof(int)*(V+1)); memset(pre,0,sizeof(int)*(V+1)); dis[S]=0;vis[S]=1;Q.push(S); while(Q.size()){ int u=Q.front();Q.pop();vis[u]=0; for(int i=frm[u];i;i=nxt[i]){ int v=to[i]; if(cap[i]>flow[i]&&dis[v]>dis[u]+cost[i]){ dis[v]=dis[u]+cost[i];pre[v]=i; if(!vis[v]){vis[v]=1;Q.push(v);} } } } return pre[T]; } pair<int,int> mcmf(){ int maxflow=0,mincost=0; while(spfa()){ int d=INF; for(int i=pre[T];i;i=pre[to[i^1]]){ d=min(d,cap[i]-flow[i]); } for(int i=pre[T];i;i=pre[to[i^1]]){ flow[i]+=d; flow[i^1]-=d; mincost+=d*cost[i]; } maxflow+=d; } return {maxflow,mincost}; }
|