和之前的那個我也不知道叫啥名字的算法一樣,我們也有bfs函數和zg函數。(爲了區分我叫他dinic函數)
在bfs()中
爲了搞的快一點,我們要找一條短一些的路(???)反正先給每個結點根據bfs到的順序標記一下深度dep數組。(反正能快嗯對沒毛病)別的和之前那個一模一樣。(這裏有個小小的優化:inque不用惹,用dep標記到過沒有就行啦)和inque一樣,dep只在bfs前清零,別的時候不要搞他畫蛇添足!
代碼在這裏!
bool bfs()
{
memset(dep,0,sizeof(dep[0])*(n+1));//(n+1)乘在sizeof外面
while(!q.empty()) q.pop();//一定要開在外面! 快!
q.push(S);dep[S]=1;
while(!q.empty())
{
int x=q.front();q.pop();
for(int i=head[x];i!=-1;i=nxt[i])
{
if(w[i]==0) continue;//不許忘!
if(!dep[v[i]])
{
q.push(v[i]);
dep[v[i]]=dep[x]+1;
}
if(v[i]==T) return 1;//一定要先標記dep再return
}
}
return 0;
}
在dinic()中
這裏就不大一樣咯。首先傳進去兩個參數(x,flow)結點和流量。rest=表示剩餘的流量(函數運行完之後就是剩餘的流量)
找和x相鄰的結點v,注意一定要判斷是否和dep的距離是否差是1!(不然你標記dep有啥p用呢)然後用k存下v用掉的流量(這邊要遞歸,參數看好啊:min(rest,w[i])
rest-=k(當rest<=0時就趕緊撤)不然到最後return 總流量-剩餘的rest
代碼在這裏
int dinic(int x,int flow)
{
if(x==T) return flow;
int rest=flow;
for(int i=head[x];i!=-1;i=nxt[i])
{
if(w[i]==0||dep[v[i]]!=dep[x]+1) continue;//!
int k=dinic(v[i],min(rest,w[i]));//!
if(k)
{
rest-=k;w[i]-=k;w[i^1]+=k;
if(rest==0) return flow;
}
}
return flow-rest;
}