1. 程式人生 > >isap最大流

isap最大流

htm -1 ext ini 註意 brush targe true sin

捉摸了好幾天,終於在弄清楚了一點isap的算法~

isap就是改進的dinic算法,進行了重貼標簽的運算,並且加入了gap優化,以及當前弧的優化,從而大大提升運算速度。具體分析已經在之前的轉載的文章中分析過了。下面是鏈接

我是鏈接~

這是我的代碼~(標註!的為第二次寫的時候需要註意的部分)

#include<bits/stdc++.h>
#define maxn 3000000 
using namespace std;

struct Edge
{
   int to,w,next;
}edge[maxn];

int n,m,s,t;
int head[maxn],gap[maxn],h[maxn],cur[maxn];

int cnt=0;

void add(int a,int b,int c)
{
   edge[cnt].w=c;
   edge[cnt].to=b;
   edge[cnt].next=head[a];
   head[a]=cnt++;
}

int  isap(int x,int fr)
{
    if(x==t)
       return fr;
    int rest=0;
    for(int i=cur[x];~i;i=edge[i].next)
    {
	    int j=edge[i].to;
	    if(h[j]+1==h[x]&&edge[i].w)//!
	     {
		    int f=isap(j,min(edge[i].w,fr-rest));
		    edge[i].w-=f;
		    edge[i^1].w+=f;
		    rest+=f;
		    if(rest==fr)  return fr;
		    if(edge[i].w) cur[x]=i;
		 }
	}
	--gap[h[x]];
	if(!gap[h[x]]) h[s]=n+2;//! 
	h[x]++;gap[h[x]]++;//進行重貼標簽
	cur[x]=head[x];
	return rest; 
}

int main()
{
   int ans=0;
   memset(head,-1,sizeof(head));
   cin>>n>>m>>s>>t;
   while(m--)
   {
      int t1,t2,t3;
      cin>>t1>>t2>>t3;
      add(t1,t2,t3);add(t2,t1,0);
   }
   for(int i=0;i<n;i++)
     cur[i]=head[i];
    while(h[s]<n+2)
      ans+=isap(s,1e9);
    cout<<ans<<endl;
   return 0;
}

isap最大流