网络流模板:最大流ISAP算法和Dinic算法

ISAP:

 

  1. #include<cstdio>  
  2. #include<cstring>  
  3. #include<queue>  
  4. #include<algorithm>  
  5. #define N 505  
  6. #define inf 999999999  
  7. using namespace std;  
  8.   
  9. int n,m,s,t,dis[N],pre[N],gap[N],flow[N][N];  
  10. struct edge  
  11. {  
  12.     int v,w;  
  13.     edge *next,*rev;  
  14.     edge(){next=0;}  
  15.     edge(int vv,int ww,edge *e){v=vv;w=ww;next=e;}  
  16. }*adj[N],*path[N],*e;  
  17. void insert(int u,int v,int w)  
  18. {  
  19.     edge *p=new edge(v,w,adj[u]);  
  20.     adj[u]=p;  
  21.     edge *q=new edge(u,0,adj[v]);  
  22.     adj[v]=q;  
  23.     p->rev=q;  
  24.     q->rev=p;  
  25. }  
  26. void bfs()  
  27. {  
  28.     memset(dis,0x7f,sizeof(dis));  
  29.     memset(gap,0,sizeof(gap));  
  30.     queue<int> q;  
  31.     dis[t]=0;  
  32.     gap[0]=1;  
  33.     q.push(t);  
  34.     while(q.size())  
  35.     {  
  36.         int x=q.front();  
  37.         q.pop();  
  38.         for(e=adj[x];e;e=e->next)  
  39.         {  
  40.             if(e->rev->w==0||dis[e->v]<t)  
  41.                 continue;  
  42.             dis[e->v]=dis[x]+1;  
  43.             ++gap[dis[e->v]];  
  44.             q.push(e->v);  
  45.         }  
  46.     }  
  47. }  
  48. int ISAP()  
  49. {  
  50.     memset(dis,0,sizeof(dis));  
  51.     memset(gap,0,sizeof(gap));  
  52.     //bfs();  
  53.     int ans=0,u=s,d;  
  54.     while(dis[s]<=t)  
  55.     {  
  56.         if(u==t)  
  57.         {  
  58.             int minflow=-1u>>1;  
  59.             for(e=path[u];u!=s;e=path[u=pre[u]])  
  60.                 minflow=min(minflow,e->w);  
  61.             for(e=path[u=t];u!=s;e=path[u=pre[u]])  
  62.             {  
  63.                 e->w-=minflow;  
  64.                 e->rev->w+=minflow;  
  65.                 flow[pre[u]][u]+=minflow;  
  66.                 flow[u][pre[u]]-=minflow;  
  67.             }  
  68.             ans+=minflow;  
  69.         }         
  70.         for(e=adj[u];e;e=e->next)  
  71.             if(e->w>0&&dis[u]==dis[e->v]+1)  
  72.                 break;  
  73.         if(e)  
  74.         {  
  75.             pre[e->v]=u;  
  76.             path[e->v]=e;  
  77.             u=e->v;  
  78.         }  
  79.         else  
  80.         {  
  81.             if(--gap[dis[u]]==0)  
  82.                 break;  
  83.             for(d=t,e=adj[u];e;e=e->next)  
  84.                 if(e->w>0)  
  85.                     d=min(d,dis[e->v]);  
  86.             dis[u]=d+1;  
  87.             ++gap[dis[u]];  
  88.             if(u!=s)  
  89.                 u=pre[u];  
  90.         }  
  91.     }  
  92.     return ans;  
  93. }  
  94. int main()  
  95. {  
  96.     int u,v,w;  
  97.     while(~scanf("%d%d",&m,&n))  
  98.     {  
  99.         memset(adj,0,sizeof(adj));  
  100.         while(m--)  
  101.         {  
  102.             scanf("%d%d%d",&u,&v,&w);  
  103.             insert(u,v,w);  
  104.             //insert(v,u,w);//无向边  
  105.         }  
  106.         s=1;  
  107.         t=n;  
  108.         printf("%d\n",ISAP());  
  109.     }  
  110. }  
  111. /* 
  112. 6 5 
  113. 3 4 5 
  114. 4 5 5 
  115. 1 2 10 
  116. 2 3 10 
  117. 1 3 20 
  118. 2 5 20 
  119.  
  120. */  


 

Dinic:

 

  1. #include<cstdio>  
  2. #include<cstring>  
  3. #include<algorithm>  
  4. #define N 5005  
  5. #define M 10005  
  6. #define inf 999999999  
  7. using namespace std;  
  8.   
  9. int n,m,s,t,num,adj[N],dis[N],q[N];  
  10. struct edge  
  11. {  
  12.     int v,w,pre;  
  13. }e[M];  
  14. void insert(int u,int v,int w)  
  15. {  
  16.     e[num]=(edge){v,w,adj[u]};  
  17.     adj[u]=num++;  
  18.     e[num]=(edge){u,0,adj[v]};  
  19.     adj[v]=num++;  
  20. }  
  21. int bfs()  
  22. {  
  23.     int i,x,v,tail=0,head=0;  
  24.     memset(dis,0,sizeof(dis));  
  25.     dis[s]=1;  
  26.     q[tail++]=s;  
  27.     while(head<tail)  
  28.     {  
  29.         x=q[head++];          
  30.         for(i=adj[x];i!=-1;i=e[i].pre)  
  31.             if(e[i].w&&dis[v=e[i].v]==0)  
  32.             {  
  33.                 dis[v]=dis[x]+1;  
  34.                 if(v==t)  
  35.                     return 1;  
  36.                 q[tail++]=v;  
  37.             }  
  38.     }  
  39.     return 0;  
  40. }  
  41. int dfs(int s,int limit)  
  42. {  
  43.     if(s==t)  
  44.         return limit;  
  45.     int i,v,tmp,cost=0;  
  46.     for(i=adj[s];i!=-1;i=e[i].pre)  
  47.         if(e[i].w&&dis[s]==dis[v=e[i].v]-1)  
  48.         {  
  49.             tmp=dfs(v,min(limit-cost,e[i].w));  
  50.             if(tmp>0)  
  51.             {  
  52.                 e[i].w-=tmp;  
  53.                 e[i^1].w+=tmp;  
  54.                 cost+=tmp;  
  55.                 if(limit==cost)  
  56.                     break;  
  57.             }  
  58.             else dis[v]=-1;  
  59.         }  
  60.     return cost;  
  61. }  
  62. int Dinic()  
  63. {  
  64.     int ans=0;  
  65.     while(bfs())  
  66.         ans+=dfs(s,INT_MAX);  
  67.     return ans;  
  68. }  
  69. int main ()  
  70. {  
  71.     while(~scanf("%d%d",&m,&n))  
  72.     {  
  73.         int u,v,w;  
  74.         memset(adj,-1,sizeof(adj));  
  75.         num=0;  
  76.         s=1;  
  77.         t=n;  
  78.         while(m--)  
  79.         {  
  80.             scanf("%d%d%d",&u,&v,&w);  
  81.             insert(u,v,w);  
  82.         }  
  83.         printf("%d\n",Dinic());  
  84.     }  


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值