一直觉得网络流很吊。。。然后就从网上找了个pdf来看
《图论与网络流》
这本书里讲述了图论的相关知识和定理。还有相关证明
特别是网络流那一章。讲的通俗易懂。。
目前为止只看了Ford-Fulkerson算法和Dinic算法
基本上看了一两遍就懂了。。

Ford-Fulkerson算法:
1)找到一条可增广的x-y路,并得出这条路上可增广的最小值min(非零)
2)沿着这条可增广的x-y路,对于这条增广路中所有边。有以下两个操作
1.如果这条边是正向的,边权减去min
2.如果这条边是方向的,边权加上min
3)重复1)&2)直到没有增广路

主体思想是这个。
具体的步骤为:

V–> 所有点集合
x–>  源点集合
y–> 汇点集合
A–>  边的流量集合
C–> 边的容量集合
F(x,y)–>  x->y这条边的流量
L–> 已标未查集合
S–> 已标已查集合
给定网络 N(V,x,y,A,C)

求最大流的步骤:
1)先把所有边的流量清空为0
2)给所有源点x标号为(x,无穷大),把x放到已标未查集里
3)从已标未查集中取出u,检查u的未标号的邻点v
1.若u–>v是正向边,并且可以有流量通过(F(u,v)<C(u,v)),给v标号为(u,+,l(v)),l(v)=min(l(u),C(u,v)-F(u,v))表示为从源点到v这个点花的最小流量(因为要加上),把v放进已标未查集
2.如果u–v是反向边,并且F(u,v)>0 给v点标号为(u,-,l(v)),l(v)=min(l(u),C(u,v)-F(u,v)),把v放到已标未查集
4)把u放到已标已查集,若汇点v被标号,走第6步,否则走第5步
5)如果已标未查集为空,算法结束,当前流是最大流;否则转第二步
6)如果v是汇点,转下一步
7)如果是已标号的汇点,如果标号为(w,+,l(v)) 那么F(w,v)+=l(v),如果标号为
(w,-,l(v))那么F(w,v)-=l(v)
8)另v=w,转第7步,否则去除所有点的标号。转第2步
算法结束

如果看懂了这个算法的话。很容易想到bfs 记录路径 处理路径这几个关键点吧。。
(这个代码没有写过,只是大概知道应该这么回事,因为我看了Dinic就放弃学习Ford-Fulkerson了)
优化过后的Ford-Fulkerson算法复杂度为O(ve2)O(ve^2) , e–>边的数量

Dinic算法:
这个算法思路跟Ford-Fulkerson的差不多。但是优化了Ford-Fulkerson的查找路径过程
算法复杂度为O(v2e)O(v^2e)还是比较可观。看起来挺吓人。但实际是到达不了的
1)构造分层网络(从源点开始的最短路,每条边的边假设为1)
给每个点标号分层,如果汇点没有获得标号,那么结束算法
假设从源点到某个点的最短路为x,那么所有从源点到某个点最短路为x的点都分为一层
2)构造辅助网络N(v)
在分层网络的基础上。对于所有的边
1.如果F(u,v)<C(u,v)F(u,v) < C(u,v) 那么F(u,v)=C(u,v)F(u,v)F'(u,v)=C(u,v)-F(u,v) , F(v,u)=F(u,v)F'(v,u)=F(u,v)
2.如果F(u,v)==C(u,v)F(u,v)==C(u,v)那么F(u,v)=C(u,v)F'(u,v)=C(u,v) , F(v,u)=0F'(v,u)=0
在分层网络的基础上在原图中删去所有同层之间的边(也不一定是删除,主要是只保留从底层到高层的边)
3)在辅助网络中找到一条x-y增广路(这条增广路上可增广的流为x>0)
对于x-y增广路上的所有边
1.如果边为正向 那么加上x
2.如果边为方向 那么减去x
4)转1

具体的步骤也没有什么好说的了。
值得一提的是  在3)这个步骤中,可以使用栈的方式来处理。
假设我找到了一条x-y增广路  1–>2–>3–>4–>5–>6
F(1,2)=10 F(2,3)=20 F(3,4)=5 F(4,5)=30 F(5,6)=40
我们可以得到这条x-y路上的最小可增广的流为5,它是3–>4这条边上的
我们可以先把这条x-y路上的所有正向边减去5 所有反向边加上5
再从3这个地方开始往下找增广路(有种东东叫做栈)
如果看到了这里。看懂了的话。完全可以自己敲出代码。。
讲到这里好了。。好累。敲了半天。= =
Dinic代码:

//author: CHC
//First Edit Time: 2014-07-29 17:19
//Last Edit Time: 2014-08-03 08:52
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <algorithm>
#include <limits.h>
using namespace std;
#define MAXN 10000
#define MAXM 100000
const int INF = INT_MAX;
typedef long long LL;
struct Edge
{
int from,to,ci,next;
Edge(){}
Edge(int _from,int _to,int _ci,int _next):from(_from),to(_to),ci(_ci),next(_next){}
}e[MAXM];
int head[MAXN],tot;
int dis[MAXN];
int top,sta[MAXN],cur[MAXN];
int n,m;
inline void init(){
memset(head,-1,sizeof(head));
tot=0;
}
inline void AddEdge(int u,int v,int ci0,int ci1=0){
e[tot]=Edge(u,v,ci0,head[u]);
head[u]=tot++;
e[tot]=Edge(v,u,ci1,head[v]);
head[v]=tot++;
}
inline bool bfs(int st,int et){
memset(dis,0,sizeof(dis));
dis[st]=1;
queue <int> q;
q.push(st);
while(!q.empty()){
int now=q.front();
q.pop();
for(int i=head[now];i!=-1;i=e[i].next){
int next=e[i].to;
if(e[i].ci&&!dis[next]){
dis[next]=dis[now]+1;
if(next==et)return true;
q.push(next);
}
}
}
return false;
}
LL Dinic(int st,int et){
LL ans=0;
while(bfs(st,et)){
top=0;
memcpy(cur,head,sizeof(head));
int u=st,i;
while(1){
if(u==et){
int pos,minn=INF;
printf("top:%d\n",top);
for(i=0;i<top;i++)
{
if(minn>e[sta[i]].ci){
minn=e[sta[i]].ci;
pos=i;
}
//printf("%d --> %d\n",e[sta[i]].from,e[sta[i]].to);
}
for(i=0;i<top;i++){
e[sta[i]].ci-=minn;
e[sta[i]^1].ci+=minn;
}
top=pos;
u=e[sta[top]].from;
ans+=minn;
//printf("minn:%d\n\n",minn);
}
for(i=cur[u];i!=-1;cur[u]=i=e[i].next)
if(e[i].ci&&dis[u]+1==dis[e[i].to])break;
if(cur[u]!=-1){
sta[top++]=cur[u];
u=e[cur[u]].to;
}
else {
if(top==0)break;
dis[u]=0;
u=e[sta[--top]].from;
}
}
}
return ans;
}
int ru[MAXN],chu[MAXN];
int main() {
while(~scanf("%d%d",&n,&m)){
init();
for(int i=0,x,y,vi,ci;i<m;i++){
scanf("%d%d%d%d",&x,&y,&vi,&ci);
AddEdge(x,y,ci-vi,vi);
ru[y]++;
chu[x]++;
}
int st,et;
for(int i=1;i<=n;i++){
if(ru[i]==0)st=i;
if(chu[i]==0)et=i;
}
//printf("st:%d et:%d\n",st,et);
//printf("%I64d\n",Dinic(st,et));
printf("st:%d et:%d\n",st,et);
printf("%I64d\n",Dinic(1,n));
}
return 0;
}
/*
7 12
1 2 3 4
1 3 3 10
2 3 1 1
2 4 0 2
3 4 1 5
3 6 3 3
2 5 2 7
4 5 0 6
4 6 1 1
6 5 0 5
5 7 2 9
6 7 4 6
ans:6
4 5
1 2 0 40
1 4 0 20
2 4 0 20
2 3 0 30
3 4 0 10
ans:50
*/