过程:
f(e):e上已流过的流量
c(e):e上允许流过的最大流量
残余网络:f(e)小于c(e)的边e && 满足f(e)>0的e对应的反向边rev(e)组成的网络
增广路:残余网络上的s–>t路径
求解最大流:就是不断找图中的增广路,每找到一条,更新一次增广路上的各边的流量及其反向边的流量。
crap:寒假以来学的第一个算法,也用它a了寒假的第一道题。
现在的话,有多想就有多害怕。未来如果失败,有多想就会有多遗憾;如果成功,有多想就会有多开心。那就尽情去害怕,尽情遗憾尽情开心吧,反正我还年轻,浪掷几年无所谓。我甘愿用一生的时间去钻研的东西也很多,不只去到那里才能实现我想过的生活。而且,我不信我会沦落到困苦的田地。
板子:
public class Main {static int MAX_V=220,INF=10000010;static ArrayList<edge> G[]=new ArrayList[MAX_V];//邻接表存图static boolean used[]=new boolean[MAX_V];//向图中添加边static void add_edge(int from,int to,int cap) {G[from].add(new edge(to,cap,G[to].size()));G[to].add(new edge(from,0,G[from].size()-1));}//DFS寻找图中增广路//v为当前所在点,t为终点,f为当前的流量static int dfs(int f,int v,int t) {if(v==t) {return f;}used[v]=true;edge e;for(int i=0;i<G[v].size();i++) {e=G[v].get(i);if(e.cap>0&&!used[e.to]) {int d=dfs(Math.min(f, e.cap),e.to,t);if(d>0) {//e的cap-=de.cap-=d;//e的反向边的cap+=dG[e.to].get(e.rev).cap+=d;return d;}}}return 0;}//求解从S到t的最大流static int max_flow(int s,int t) {int flow=0;for(;;) {for(int i=0;i<MAX_V;i++) {used[i]=false;}int f=dfs(INF,s,t);if(f==0) {return flow;}flow+=f;}}public static void main(String args[]) throws IOException{PrintWriter out=new PrintWriter(System.out);InputReader sc=new InputReader(System.in);while(true) {int N=sc.nextInt();int M=sc.nextInt();int u,v,c;for(int i=1;i<=M;i++) {G[i]=new ArrayList<edge>();}for(int i=0;i<N;i++) {u=sc.nextInt();v=sc.nextInt();c=sc.nextInt();add_edge(u, v, c);}out.println(max_flow(1,M));out.flush();}}
}
class edge{int to,cap,rev;//to 为该边指向的点,cap为该边当前还剩的流量,rev为这个边的反向边在G[to]中的下标。public edge(int to,int cap,int rev) {this.to=to;this.cap=cap;this.rev=rev;}
}