最小费用最大流板子(JAVA)

版权声明: https://blog.csdn.net/King8611/article/details/83268224

板子题: 洛谷P3381 【模板】最小费用最大流

https://www.luogu.org/problemnew/show/P3381

import java.util.*;
import java.io.*;
public class Main {
	static int v,m,s,t,f;												//点的个数,边的个数,源点,汇点,流量。														
	static final int inf=1<<30;											//无穷大0
	static ArrayList<Edge> g[];											//图的邻接表表示
	static int len;														//表示当前储存边的个数
	static int dist[];													//最短距离
	static int prevv[],preve[];											//最短路中的前驱节点和对应的边
	static int h[];														//顶点的势
	static StreamTokenizer in=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in))); 
	static void addEdge(int from,int to,int cap,int cost) {
		g[from].add(new Edge(to,cap,cost,g[to].size()));
		g[to].add(new Edge(from,0,-cost,g[from].size()-1));
	}
	static int min_cost(int s,int t) {
		int res=0;
		for(int i=0;i<=v;i++) 
			h[i]=0;
		while(true) {
			for(int i=0;i<=v;i++) 
				dist[i]=inf;
			dist[s]=0;
			PriorityQueue<P> list=new PriorityQueue<P>();
			list.offer(new P(0,s));
			while(!list.isEmpty()) {
				P p=list.poll();
				int v=p.b;
				if(dist[v]<p.a)continue;
				for(int i=0;i<g[v].size();i++) {
					Edge e=g[v].get(i);
					if(e.cap>0&&dist[e.to]>dist[v]+e.cost+h[v]-h[e.to]) {
						dist[e.to]=dist[v]+e.cost+h[v]-h[e.to];
						prevv[e.to]=v;
						preve[e.to]=i;
						list.add(new P(dist[e.to],e.to));
					}
				}
			}
			if(dist[t]==inf) {
				break;
			}
			for(int u=1;u<=v;u++)h[u]+=dist[u];
			int d=inf;
			for(int v=t;v!=s;v=prevv[v]) {
				d=Math.min(d,g[prevv[v]].get(preve[v]).cap);
			}
			f+=d;
			res+=d*h[t];
			//System.out.println(res+" "+d+" "+h[t]);
			for(int v=t;v!=s;v=prevv[v]) {
				Edge e=g[prevv[v]].get(preve[v]);
				e.cap-=d;
				g[v].get(e.rev).cap+=d;
			}
		}
		return res;
	}
	public static void main(String[] args)throws Exception {
			v=getInt();
			m=getInt();
			s=getInt();
			t=getInt();
			init();
			for(int i=0;i<m;i++) {
				addEdge(getInt(),getInt(),getInt(),getInt());
			}
			int ans=min_cost(s,t);
			System.out.println(f+" "+ans);
	}
	static void init() {
		h=new int[v+1];
		f=0;
		g=new ArrayList[v+1];
		for(int i=0;i<=v;i++) {
			g[i]=new ArrayList<Edge>();
		}
		dist=new int[v+1];
		prevv=new int[v+1];
		preve=new int[v+1];
	}
	static int getInt() throws Exception{
		in.nextToken();
		return (int)in.nval;
	}
}
class Edge{
	int to,cap,cost,rev;											//终点,容量,费用,反向边
	public Edge(int a,int b,int c,int d) {
		to=a;
		cap=b;
		cost=c;
		rev=d;
	}
}
class P implements Comparable{
	int a,b;
	public P(int a,int b) {
		this.a=a;
		this.b=b;
	}
	public int compareTo(Object o) {
		P p=(P)o;
		return this.a-p.a;
	}
}

猜你喜欢

转载自blog.csdn.net/King8611/article/details/83268224