NOIp……应该不会考这东西吧QAQ
考了感觉药丸。。
还是整一个比较好~
网络流有个特点就是,最坏的上界一般都是达不到的。
1.FF
思路是每次增广1的流量,很慢的,因为容量一般挺大,
没写过,就没模板了。。O(
|f|∗m
)(似乎是,有点忘了)
2.EK
思路是随意找一条增广路径,然后增广即可。
最坏O(
m2n
)。
就写过一次……还是早期写的……真是有点丑的。。
bool EdKa(int src,int des,int n)
{
int v,i,head,tail;
memset(visit,0,sizeof(visit));
head=tail=0;
Q[tail++]=src;
visit[src]=true;
while (head!=tail)
{
v=Q[head++];
for (i=1;i<=n;i++)
if (!visit[i] && map[v][i])
{
Q[tail++]=i;
visit[i]=true;
pre[i]=v;
if (i==des) return true;
}
}
return false;
}
int maxflow(int src,int des,int n)
{
int i,_min,sum=0;
while (true)
{
if (!EdKa(src,des,n))
return sum;
_min=(1<<30);
i=des;
while (i!=src)
{
if (_min>map[pre[i]][i])
_min=map[pre[i]][i];
i=pre[i];
}
i=des;
while (i!=src)
{
map[pre[i]][i]-=_min;
map[i][pre[i]]+=_min;
i=pre[i];
}
sum+=_min;
}
}
3.dinic
不会。O(
n2m
)
什么?我竟然不会dinic??
对啊……因为我菜啊。。
QAQ好吧不过幸好网上dinic模板一堆一堆的,随便找啦!
4.ISAP
一直在用的网络流写法……
也是O(
n2m
)的,综合来说应该比dinic快一丢。
每次找最短路增广,然后加上当前弧优化(Improved SAP)
然后可以一开始预处理出层次网络(我的写法)。
用BFS预处理出初始层次网络,不过似乎可以中间计算出来?
测试了很多题,觉得这个模板还不错,速度也还可以。
void BFS(){
memset(gap,0,sizeof(gap));
memset(d,255,sizeof(d));
d[sink]=0; gap[0]++;
int Head=0,tail=1;
Q[0]=sink;
while (Head!=tail){
int u=Q[Head++];
for (int i=head[u];~i;i=E[i].next){
int j=E[i].to;
if (~d[j]) continue;
d[j]=d[u]+1;
gap[d[j]]++;
Q[tail++]=j;
}
}
}
int ISAP(){
BFS();
memcpy(cur,head,sizeof(cur));
int u,flow=0;
u=pre[source]=source;
while (d[sink]<Ver+1){
if (u==sink){
int f=inf,neck;
for (int i=source;i!=sink;i=E[cur[i]].to)
if (f>E[cur[i]].C) f=E[cur[i]].C,neck=i;
for (int i=source;i!=sink;i=E[cur[i]].to)
E[cur[i]].C-=f,E[cur[i]^1].C+=f;
flow+=f; u=neck;
}
int j;
for (j=cur[u];~j;j=E[j].next)
if (E[j].C && d[E[j].to]+1==d[u]) break;
if (~j){
pre[E[j].to]=u;
cur[u]=j;
u=E[j].to;
} else{
if (!(--gap[d[u]])) break;
int mind=Ver+1;
for (int i=head[u];~i;i=E[i].next)
if (E[i].C && mind>d[E[i].to])
cur[u]=i,mind=d[E[i].to];
d[u]=mind+1;
gap[d[u]]++;
u=pre[u];
}
}
return flow;
}
最小费用最大流:
只会最小费用最大流啊。。什么最大费用,最小流这种都不会。。
突然发现以前写过了。。传送门