ISAP

[置顶]【整合】网络流ISAP算法模板

  1. 注释应该比较清楚了吧= = 
注释应该比较清楚了吧= =
  1. #include<iostream> 
  2. #include<cstdio> 
  3. #include<cstring> 
  4. #include<cmath> 
  5. #include<algorithm> 
  6. #define MAXN 2048 
  7. #define MAXINT 0x7fffffff 
  8. using namespace std; 
  9. int n,m;//点的数目和边的数目 
  10. int dis[MAXN+1];//距离标号  
  11. int num[MAXN+1]; 
  12. int src,des;//src源点,des汇点  
  13. int u,v,w; 
  14. struct edge 
  15.     int f;//某条弧当前流量  
  16.     int c;//容量 
  17.     int ver;//弧的起点 
  18.     edge *rev;//反弧  
  19.     edge *next;//弧的终点  
  20.     edge(){}; 
  21.     edge(int v,int cap,edge *nex):ver(v),c(cap),next(nex),rev(NULL),f(0){}; 
  22.     void* operator new(size_t, void *p) 
  23.     { 
  24.         return p; 
  25.     } 
  26. }*s[MAXN+1]; 
  27. void init() 
  28.     int queue[MAXN+1],head=0,tail=0; 
  29.     for (int i=1;i<=n;i++) 
  30.         dis[i]=MAXN,num[i]=0; 
  31.     queue[tail++]=des; 
  32.     dis[des]=0; 
  33.     num[0]=1; 
  34.     while (head!=tail) 
  35.     { 
  36.         int v=queue[head++]; 
  37.         edge *e=s[v]; 
  38.         while (e) 
  39.         { 
  40.             if ((e->rev)&&(e->rev->c==0)||dis[e->ver]<MAXN) {}//若改点后的边不可通过 
  41.             //流或者已经更新就无需更新 
  42.             else  
  43.             { 
  44.                 dis[e->ver]=dis[v]+1; 
  45.                 ++num[dis[e->ver]]; 
  46.                 queue[tail++]=e->ver; 
  47.             } 
  48.             e=e->next; 
  49.         } 
  50.     } 
  51. int maxflow()//ISAP算法实现过程  
  52.     int st=src,ret=0; 
  53.     edge *E[MAXN],*rep[MAXN]; 
  54.     for (int i=1;i<=n;i++) E[i]=s[i]; 
  55.     while (dis[src]<n)//不存在增广路径就停止  
  56.     { 
  57.         if (st==des)//找到了增广路径  
  58.         { 
  59.             int delta=MAXINT; 
  60.             for (int i=src;i!=des;i=E[i]->ver) 
  61.                 delta=min(delta,E[i]->c); 
  62.             for (int i=src;i!=des;i=E[i]->ver) 
  63.             { 
  64.                 E[i]->c-=delta; 
  65.                 E[i]->f+=delta; 
  66.                 E[i]->rev->c+=delta; 
  67.                 E[i]->rev->f-=delta; 
  68.             } 
  69.             ret+=delta; 
  70.             st=src; 
  71.         } 
  72.         edge *e; 
  73.         for (e=E[st];e;e=e->next) 
  74.             if (e->c>0&&dis[st]==dis[e->ver]+1) break
  75.         if (e)//存在允许弧  
  76.         { 
  77.             E[st]=e; 
  78.             rep[e->ver]=e->rev; 
  79.             st=e->ver; 
  80.         } 
  81.         else 
  82.         { 
  83.             if ((--num[dis[st]])==0) break;//GAP优化  
  84.             E[st]=s[st]; 
  85.             int mind=n; 
  86.             for (edge *t=s[st];t;t=t->next) 
  87.                 if (t->c>0) 
  88.                     mind=min(mind,dis[t->ver]); 
  89.             dis[st]=mind+1; 
  90.             ++num[dis[st]]; 
  91.             if (st!=src) st=rep[st]->ver; 
  92.         } 
  93.     } 
  94.     return ret; 
  95. int main() 
  96.     freopen("ditch.in","r",stdin); 
  97.     freopen("ditch.out","w",stdout); 
  98.     scanf("%d%d",&m,&n); 
  99.     src=1,des=n; 
  100.     edge *buffer=new edge[2*m]; 
  101.     edge *data=buffer; 
  102.     while (m--) 
  103.     { 
  104.         scanf("%d%d%d",&u,&v,&w); 
  105.         s[u]=new((void*) data++) edge(v,w,s[u]); 
  106.         s[v]=new((void*) data++) edge(u,0,s[v]); 
  107.         s[u]->rev=s[v]; 
  108.         s[v]->rev=s[u]; 
  109.     } 
  110.     init(); 
  111.     printf("%d",maxflow()); 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值