關於網絡流的新的總結(dinic)

和之前的那個我也不知道叫啥名字的算法一樣,我們也有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;
} 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章